无法在java方法中正确验证平衡括号解析

时间:2015-11-05 20:35:38

标签: java algorithm data-structures

我有一个方法可以使用java验证字符串中准确的开括号和右括号。此方法将用于解析数学表达式,因此对括号进行平衡非常重要。出于某种原因,它在这两个运行中都返回false:

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;
    }

}

这是我正在使用的堆栈类:

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);
    }
}

2 个答案:

答案 0 :(得分:6)

当前的问题是这个

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

如果您使用java 1.7或更少,则首先给出char =“”,因此您将退出循环,因为堆栈为空...

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

中更改

更改为:

char[] tokens = str.toCharArray();

我想你需要考虑这样一个事实:在你的第一个(之前可能有字符,而你可能有其他字符()

答案 1 :(得分: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;
}
相关问题