Java 使用堆栈分析(ABC)^n的字符串
我有一个带有As、Bs和Cs的字符串,我需要对一种语言(ABC)^n进行分析,其中n>0。如果该字符串为“abcabc”,则为真;如果为“ABAB”或“AB”,则为假。当它读取一行“AB”然后停止程序时,我总是将错误消息字符串索引超出范围。 以下是我的代码:Java 使用堆栈分析(ABC)^n的字符串,java,string,Java,String,我有一个带有As、Bs和Cs的字符串,我需要对一种语言(ABC)^n进行分析,其中n>0。如果该字符串为“abcabc”,则为真;如果为“ABAB”或“AB”,则为假。当它读取一行“AB”然后停止程序时,我总是将错误消息字符串索引超出范围。 以下是我的代码: public boolean isABC(String line) throws StackException{ MyStack Stack = new MyStack(); // initialize loop coun
public boolean isABC(String line) throws StackException{
MyStack Stack = new MyStack();
// initialize loop counters
int i = 0;
int n = line.length();
char ch = line.charAt(i);
// Push all 'A's to L6Stack
while (i < line.length()){
if(line.charAt(i) == 'A'){
L6Stack.push(ch);
i++;
if(line.charAt(i)=='B'){
L6Stack.push(ch);
i++;
if(line.charAt(i) =='C'){
L6Stack.push(ch);
i++;
}else
break;
}else
break;
}else
break;
}
if (i == n ){
return true;
}else
return false;
}
public boolean isbc(字符串行)抛出堆栈异常{
MyStack Stack=新MyStack();
//初始化循环计数器
int i=0;
int n=line.length();
char ch=line.charAt(i);
//将所有“A”推送到L6Stack
而(i
如果字符串长度为2(“AB”),那么当您到达
if(line.charAt(i) =='C')
i
的值将为2
。长度为2的字符串仅在位置0
和1
处有字符。如果使用charAt(2)
则试图读取字符串末尾以外的内容,从而导致异常
现在,只要输入字符串长度不是3个字符的倍数,就会出现错误 如果字符串长度为2(“AB”),那么当您到达
if(line.charAt(i) =='C')
i
的值将为2
。长度为2的字符串仅在位置0
和1
处有字符。如果使用charAt(2)
则试图读取字符串末尾以外的内容,从而导致异常
现在,只要输入字符串长度不是3个字符的倍数,就会出现错误 您的代码在检查是否可以在不越界的情况下前进3个字符之前尝试前进。如果(i==n)返回false,您可以通过将所有
i++
替换为来修复它;i++
。但是,您也可以将其全部重写为更干净:
试试这个:
public boolean isABC(String line) {
int total = line.length();
int position = 0;
char prev = 'C';
while (position < total) {
char c = line.get(position++);
switch (c) {
case 'A': if (prev != 'C') return false; break;
case 'B': if (prev != 'A') return false; break;
case 'C': if (prev != 'B') return false; break;
}
prev = c;
}
return prev == 'C';
}
您的代码在检查是否可以在不越界的情况下前进3个字符之前尝试前进。如果(i==n)返回false,您可以通过将所有
i++
替换为来修复它;i++
。但是,您也可以将其全部重写为更干净:
试试这个:
public boolean isABC(String line) {
int total = line.length();
int position = 0;
char prev = 'C';
while (position < total) {
char c = line.get(position++);
switch (c) {
case 'A': if (prev != 'C') return false; break;
case 'B': if (prev != 'A') return false; break;
case 'C': if (prev != 'B') return false; break;
}
prev = c;
}
return prev == 'C';
}
我不会纠正你的逻辑,但我会尽力解释你为什么会得到SIOOB异常。请参阅内联注释 比方说 line=“AB”; 所以
length=2
和i=0
while (i < line.length()){//this condition returns true.
if(line.charAt(i) == 'A'){// you are trying to access 0th Element.
L6Stack.push(ch);
i++;// i is 1 now.
if(line.charAt(i)=='B'){// trying to access 1st element.
L6Stack.push(ch);
i++;//i is 2 now.
if(line.charAt(i) =='C'){// trying to access 2st element. which would give you exception because there is no 2nd element.
L6Stack.push(ch);
i++;
}else
break;
}else
break;
}else
break;
}
while(i
我不打算更正您的逻辑,但我将尝试解释您为什么会出现SIOOB异常。请参阅内联注释
比方说
line=“AB”;
所以length=2
和i=0
while (i < line.length()){//this condition returns true.
if(line.charAt(i) == 'A'){// you are trying to access 0th Element.
L6Stack.push(ch);
i++;// i is 1 now.
if(line.charAt(i)=='B'){// trying to access 1st element.
L6Stack.push(ch);
i++;//i is 2 now.
if(line.charAt(i) =='C'){// trying to access 2st element. which would give you exception because there is no 2nd element.
L6Stack.push(ch);
i++;
}else
break;
}else
break;
}else
break;
}
while(i
您不使用正则表达式的任何原因?是的,正则表达式将是解决此类问题的一个很好的选择……。为什么不使用它???如果第一个字符不等于a会发生什么?您应该学会调试代码。有几个错误。第一个是在进入while循环之前访问line.charAt(i)
。可能根本没有字符,变量甚至可能是null
。第二种方法是总是读取三个字符的块,而不检查字符串是否足够长;因此IOOBE。如果你先通过AB A,那么它会做i++第二个B,那么它会做i++下一个,那么你仍然没有试图阅读charAt(i)对于C,索引越界执行有什么原因不使用正则表达式?是的,正则表达式将是解决此类问题的一个很好的选择…….为什么不使用它???如果第一个字符不等于a会发生什么?您应该学会调试代码。有几个错误。第一个是在进入while循环之前访问line.charAt(i)
。可能根本没有字符,变量甚至可能是null
。第二种方法是总是读取三个字符的块,而不检查字符串是否足够长;因此,IOOBE。如果你首先通过AB A,那么它将做i++第二个B,那么它将做i++下一个,你仍然没有尝试读取C的字符(i),所以索引越界执行我们必须使用堆栈是为什么:-(添加了一个基于堆栈的变体。它本质上是相同的,但现在您看到的是从末尾开始的字符,而不是从开头开始的字符。第一个循环用于填充堆栈。好的,这更有意义。谢谢!我们必须使用堆栈。)