#java #string
#java #строка
Вопрос:
У меня есть строка символов с As, Bs и Cs, которые мне нужно проанализировать для языка (ABC) ^ n, где n> 0. Если эта строка «ABCABCABC», это правда, если это «ABAB» или «AB», это не правда. Я продолжаю получать строковый индекс сообщения об ошибке за пределы, когда он считывает строку «AB», а затем останавливает программу. Вот код, который у меня есть:
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;
}
Комментарии:
1. По какой-либо причине вы не используете регулярное выражение?
2. Да, регулярное выражение будет хорошим вариантом для решения таких проблем ……..Почему бы вам не использовать его????
3. Что произойдет, если первый символ не равен A?
4. Вы должны научиться отлаживать свой код. Есть несколько ошибок. Первый — получить доступ
line.charAt(i)
перед переходом в цикл while. Символа может вообще не быть, и переменная может даже бытьnull
. Второй — всегда читать фрагменты из трех символов, не проверяя, достаточно ли длинная строка; таким образом, IOOBE.5. если вы передали AB сначала A, так что это будет делать i , второй B, так что это будет делать i далее, вы все еще ничего не пытаетесь прочитать charAt (i) для C, поэтому индексируйте из связанного исполнения
Ответ №1:
Ваш код пытается продвинуть 3 символа, прежде чем проверять, может ли он сделать это, не выходя за рамки. Вы можете исправить это, заменив все i
на if (i==n) return false; 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';
}
Вы также могли бы добавить их все в стек, а затем pop()
в стек (так char c = stack.pop()
, изменив логику), но это действительно не обязательно для этого конкретного выражения.
Редактировать: добавлен вариант на основе стека:
public boolean isABC(String line) {
// fill stack
Stack<Character> stack = new Stack<Character>();
for (int i=0; i<line.length(); i ) {
stack.push(line[i]);
}
// reverse operations while popping from stack
char prev = 'A';
while ( ! stack.isEmpty()) {
char c = stack.pop();
switch (c) {
case 'A': if (prev != 'B') return false; break;
case 'B': if (prev != 'C') return false; break;
case 'C': if (prev != 'A') return false; break;
}
prev = c;
}
return prev == 'A';
}
Комментарии:
1. Мы должны использовать стеки, вот почему. 🙁
2. Добавлен вариант на основе стека. По сути, это то же самое, но теперь вы смотрите на символы, начинающиеся с конца, а не с начала. Первый цикл используется для заполнения стека.
3. Хорошо, это имеет больше смысла. Спасибо!
Ответ №2:
Если длина строки равна двум («AB»), то когда вы доберетесь до
if(line.charAt(i) =='C')
значение i
будет 2
. Строка длиной два содержит символы только в позициях 0
и 1
. Если вы используете charAt(2)
, вы пытаетесь прочитать дальше конца строки, что приводит к исключению.
Прямо сейчас вы получите сообщение об ошибке всякий раз, когда длина входной строки не кратна 3 символам.
Ответ №3:
Я не собираюсь исправлять вашу логику, но я попытаюсь объяснить, почему вы получаете исключение SIOOB. Смотрите встроенные комментарии.
Допустим, строка = «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;
}