堆栈,括号匹配

时间:2014-02-26 18:46:02

标签: java linked-list stack postfix-notation infix-notation

所以我正在用PostFix和Infix Expressions做一些功课。我遇到了一些问题,似乎无法找到我遇到问题的地方。在大多数情况下,我可以让Infix到Postfix工作......当我不想打印时,我得到(或)打印的一些方程式。此外,当我没有匹配的括号时,我没有得到像我想要的错误。

public String Infix(String equation) throws Exception{
    Stack stack=new Stack();
    boolean parensMatch=false;
    int priority=0;
    String temp="";
    for(int i=0; i<equation.length(); i++){
        char c=equation.charAt(i);
        //if the character is equal to left paren, push
        if(c=='('){
            stack.push(c);
        }
        //if the character is equal to right paren, we start popping until we find a match
        else if(c==')'){
            try{
                while(stack.peek()!='('){
                    temp+=stack.pop();
                }

                if(stack.peek()=='('){
                    char ch=stack.pop();
                    parensMatch=true;
                }

                if(parensMatch==false){
                    throw new Exception("Parens Not Match Error");
                }
            }catch(Exception e){
                System.out.println(e);
            }
            parensMatch=false;
        }
        //if the character is equal to an operator, we do some extra work
        //to figure out what is going to happen
        else if(c=='+' || c=='-' || c=='*' || c=='/' || c=='^'){
            char top=stack.peek();
            if(top=='^')
                priority=2;
            else if(top=='*' || top=='/')
                priority=1;
            else
                priority=0;
            if(priority==2){
                if(c=='*' || c=='/'){
                    temp+=stack.pop();
                }
                else if(c=='+' || c=='-'){
                    temp+=stack.pop();
                }
                else{
                    temp+=stack.pop();
                }
            }
            else{
                if(c=='*' || c=='/'){
                    temp+=stack.pop();
                    stack.push(c);
                }
                else if(c=='+' || c=='-'){
                    stack.push(c);
                }
                else{
                    stack.push(c);
                }
            }
        }
        //if the character is a space, we ignore it and move on
        else if(c==' '){
            ;
        }
        //if the character is a letter, we add it to the string
        else{
            temp+=c;
        }
    }
    int len = stack.size();
    for (int j = 0; j < len; j++)
       temp+=stack.pop();
    return temp;
}

这是我的Infix to Postfix方法

(((A + B) - (C - D)) / (E - F))这是我需要解决的表达式之一,AB+CD--(EF-/是我在打印到屏幕时得到的。 ((A是另一个,这个应该给我一个错误,但A((会打印到屏幕上。

我已经运行了很长一段时间的调试,似乎无法到达任何地方。

任何帮助都会非常有帮助。我知道它与发布的代码有关,但我找不到逻辑错误。提前谢谢!

所以我添加了一个新函数来帮助匹配我觉得有用的parens。它取了等式,只计算它们是否匹配。

public static int matchingParens(String equation){
    int match=0;

    for(int i=0; i<equation.length(); i++){
        char c=equation.charAt(i);
        if(c=='(')
            match++;
        else if(c==')')
            match--;
        else
            ;
    }

    return match;
}

2 个答案:

答案 0 :(得分:0)

要验证括号是否全部匹配,您可以使用初始值为0的计数器运行数学表达式的String输入,如果找到(,则将计数器递增1,并且如果找到),则将计数器递减1.如果计数器达到-1,则突破,因为它不是有效的括号匹配。最后,您应该将计数器的值设为0.如果不是,则表示括号不匹配。

对于中缀到后缀的情况,这是一个标准算法:

Define a stack
Go through each character in the string
If it is between 0 to 9, append it to output string.
If it is left brace push to stack
If it is operator *,+,- or / then 
          If the stack is empty push it to the stack
          If the stack is not empty then start a loop:
                             If the top of the stack has higher precedence
                             Then pop and append to output string
                             Else break
                     Push to the stack

If it is right brace then
            While stack not empty and top not equal to left brace
            Pop from stack and append to output string
            Finally pop out the left brace.

答案 1 :(得分:0)

好吧,我想给你一些“软件工程”技巧,这最终可以解决你的问题,你可以通过“好”来学习很多东西。

数学表达式,无论你是以pre,in,post顺序编写它们,如果将它们存储在某种树结构中,它们看起来总是一样的。

然后,如果你想将那个树结构打印成String,你只需要遍历整个树,当你把它写到那个字符串时,它只会在当下(以及某些情况下的附加括号)变化。

预先订购当你第一次进入那个节点时,按顺序完成左子和后序,如果你在离开那个节点时这样做。

我的建议:

分类:ExpressionUnaryExpression extends ExpressionBinaryExpression extedns Expression然后您可以创建数字和运算符:Add extends BinaryExpression等。

然后你应该有一个Tree课,它存储Expression root,它有方法printPreOrder()printInOrder()printPostOrder()

要创建该树,使用可以像这样使用的Builder pattern会非常好:

public class Director {
    private IExpressionBuilder builder;

    public ArithmeticExpression construct(String text){
                for (int i=0;i<text.length();i++){
                    if (text.charAt(i) == '+'){
                        builder.buildAddOperator();
                    }
                    ...
                }
    }  

然后您创建具体的Builder类,如下所示:

public class InOrderBuilder implements IExpressionBuilder {

    public void buildAddOperator() {
        ...
    }
    ....
}