繁体   English   中英

使用堆栈分析(ABC)^ n的字符串

[英]Analyze a string of characters for (ABC)^n using stacks

我有一个带有As,Bs和Cs的字符串,需要分析一种语言(ABC)^ n,其中n> 0。 如果此字符串是“ ABCABCABC”,则为true,如果为“ ABAB”或“ AB”,则为true。 当它读取“ 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;
}

您的代码尝试先检查3个字符,然后再检查是否可以这样做,而不会超出范围。 您可以通过将所有i++替换为if (i==n) return false; i++来解决此问题if (i==n) return false; 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';
}

如果字符串长度为两个(“ AB”),则当

if(line.charAt(i) =='C')

i的值将为2 长度为2的字符串仅在位置01处具有字符。 如果使用charAt(2) ,则尝试读取字符串末尾以外的内容,从而导致异常。

现在,只要输入的字符串长度不是3个字符的倍数,就会出现错误。

我不会纠正您的逻辑,但是我将尝试解释为什么您会收到SIOOB异常。 查看内联注释。

假设line =“ AB”; 所以length = 2i = 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;
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM