2015-11-05 61 views
0

我有一个方法,它应该验证在使用java的字符串中准确打开和关闭括号。这个方法将被用来解析数学表达式,所以对括号进行平衡很重要。出于某种原因,它在这两个运行的返回false:无法正确验证java方法中的平衡括号解析

System.out.println(parChecker("(()")); // returns false :-) 
System.out.println(parChecker("((()))")); // returns false :-( WHY?? 

下面是一个使用栈来解决问题的方法。有些事情是错误的,因为它也是一个平衡的括号。有什么问题?先谢谢你。

public static boolean parChecker(String str) { 
    String[] tokens = str.split(""); 
    int size = tokens.length; 
    Stack theStack = new Stack(size); 
    int index = 0; 
    boolean balanced = true; 
    while ((index < size) && balanced) { 
     String symbol = tokens[index]; 
     if (symbol.equals("(")) { 
      theStack.push(symbol); 
     } else { 
      if (theStack.isEmpty()) { 
       balanced = false; 
      } else { 
       theStack.pop(); 
      } 
     } 
     index++; 
    } 

    if (balanced && theStack.isEmpty()) { 
     return true; 
    } else { 
     return false; 
    } 

} 

下面是我用我的Stack类:

public class Stack { 

    private Object [] stack; 
    private int maxSize = 0; 
    private int top; 

    public Stack(int size){ 
     maxSize = size; 
     stack = new Object[maxSize]; 
     top = -1; 
    } 

    public void push(Object obj){ 
     top++; 
     stack[top] = obj; 
    } 

    public Object pop(){ 
     return stack[top--]; 
    } 

    public Object peek(){ 
     return stack[top]; 
    } 

    public boolean isEmpty(){ 
     return (top == -1); 
    } 

    public boolean isFull(){ 
     return (top == maxSize -1); 
    } 
} 
+0

为什么不要只用调试它? – manouti

+0

如果您确实想要解析算术表达式,请创建一个语法。根据语法,创建一个解析器,它将为您提供一个抽象语法树。您可能想了解一些基本的编译器技术。如果你一直这样做,你的代码会变得混乱,我保证它。 – Turing85

+0

我的目标是学习使用堆栈数据结构。这是它的一个用处。否则,我不关心解析器。让我们回到这个问题。任何想法为什么它返回一个错误? – Doublespeed

回答

6

眼前的问题是这样的

String[] tokens = str.split(""); 

给你第一个字符= “” 如果你使用java 1.7以下,所以你会退出你的循环,因为堆栈是空的...

注意:这已在java 1.8split difference between java 1.7 and 1.8

变化:

char[] tokens = str.toCharArray(); 

然而,我想,你需要考虑的是,有可能在你的第一(是字符,而您可能有其他字符,然后()

+0

嗯?不,这不是问题。拆分字符串将返回String中的一组令牌。 – Doublespeed

+0

此外,您不能将'char []'赋值给'String []'。 – Kenney

+1

@Doublespeed请使用'System.out.println(Arrays.toString(tokens))')查看分割的结果。 Peter Friberg说得对。 – RealSkeptic

3

据我所知,代码没有问题(证明这是一个Java 7特定问题。))。

我想,虽然提供了一个替代方法,用于教育目的,就是短,并且是宽容的其他人物存在:

public static boolean parChecker(String str) { 
    Stack stack = new Stack(str.length()); 
    for (char c : str.toCharArray()) 
     switch (c) { 
     case '(': 
      stack.push(c); 
      break; 
     case ')': 
      if (stack.isEmpty() || stack.pop() != Character.valueOf('(')) 
       return false; 
     } 
    return stack.isEmpty(); 
} 

按照要求,这里是另一种解决方案是不使用堆栈:

public static boolean parChecker(String str) { 
    str = str.replaceAll("[^()]", ""); 
    while (str.contains("()")) 
     str = str.replace("()", ""); 
    return str.isEmpty(); 
} 

还有一对道路:@ FredK的算法:

public static boolean parChecker(String str) { 
    int depth = 0; 
    for (char c : str.toCharArray())  
     if ((depth += c == '(' ? 1 : c == ')' ? -1 : 0) < 0) 
      return false; 
    return depth == 0; 
} 
+0

为肯尼投票..我的主要是调试答案,即使有些问题存在; ) –

+0

谢谢!我提高了这一点。但@Petter你指出了我的代码到底是什么问题,并揭示了string.split的螺丝。所以我不得不接受你的答案。但是这个答案是处理代码的好方法。 – Doublespeed

+0

@PetterFriberg谢谢!你也值得你的选票,因为你的努力!虽然,我一直无法获得一个空字符串:'for(String s:“()”。split(“”)) \t \t \t System.out.println(s);' – Kenney