无法评估中缀表达式

时间:2015-09-22 21:17:22

标签: java

我试图创建一个程序,它将接受一个无错误的中缀表达式并使用两个堆栈进行评估。对于大多数情况,它工作得很好,但带括号的表达式会使程序崩溃,而表达式如2 - 3 + 4 * 5/6输出6.33,而答案是2.33。这是一项家庭作业,所以任何提示都会有所帮助。

import java.util.Stack;
import java.util.StringTokenizer;

public class InfixEvaluation<T> extends Stack<T>{
private static final long serialVersionUID = 1L;

public static boolean isNumber(String string) {
    try {
        Double.parseDouble(string);
    } catch (Exception e) {
        return false;
    }
    return true;
}

 public static boolean hasPrecedence(char num1, char num2) {
        if ((num1 == '+' || num1 == '-') && (num2 == '*' || num2 == '/'))
            return false;
        else
            return true;
 }

public static Double evaluateInfix(String expression) {
    double result = 0;
    StringTokenizer tokens = new StringTokenizer(expression, " ");
    Stack<Character> operatorStack = new Stack<Character>();
    Stack<Double> valueStack = new Stack<Double>();

    while(tokens.hasMoreTokens()) {
        String nextToken = tokens.nextToken();
        //System.out.println(nextToken);

        if(isNumber(nextToken)) 
            valueStack.push(Double.parseDouble(nextToken));
        if(nextToken.equals("^"))
            operatorStack.push(nextToken.charAt(0));
        if(nextToken.equals("("))
            operatorStack.push(nextToken.charAt(0));
        if(nextToken.equals("+") || nextToken.equals("-") || nextToken.equals("*") || nextToken.equals("/")) {
            while(!operatorStack.empty() && hasPrecedence(operatorStack.peek(),nextToken.charAt(0))) {
                Double operand1 = valueStack.pop();
                Double operand2 = valueStack.pop();
                Character operator = operatorStack.pop();

                if(operator.equals('+'))
                    result = operand1 + operand2;
                else if(operator.equals('^'))
                    result = Math.pow(operand2, operand1);
                else if(operator.equals('-'))
                    result = operand2 - operand1;
                else if(operator.equals('*'))
                    result = operand1 * operand2;
                else
                    result = operand2 / operand1;

                valueStack.push(result);    
            }
            operatorStack.push(nextToken.charAt(0));
        }
        if(nextToken.equals(")")) {
            while(!operatorStack.peek().equals("(")) {
                Double operand1 = valueStack.pop();
                Double operand2 = valueStack.pop();
                Character operator = operatorStack.pop();

                if(operator.equals('+'))
                    result = operand1 + operand2;
                else if(operator.equals('^'))
                    result = Math.pow(operand2, operand1);
                else if(operator.equals('-'))
                    result = operand2 - operand1;
                else if(operator.equals('*'))
                    result = operand1 * operand2;
                else
                    result = operand2 / operand1;

                valueStack.push(result);

            }
            operatorStack.pop();
        }
    }


    while(!operatorStack.empty()) {
        Double operand1 = valueStack.pop();
        Double operand2 = valueStack.pop();
        Character operator = operatorStack.pop();



        if(operator.equals('+'))
            result = operand1 + operand2;
        else if(operator.equals('^'))
            result = Math.pow(operand2, operand1);
        else if(operator.equals('-'))
            result = operand2 - operand1;
        else if(operator.equals('*'))
            result = operand1 * operand2;
        else
            result = operand2 / operand1;

        valueStack.push(result);
    }




    return valueStack.peek();
 }

}

当我放入括号时,会出现:

Exception in thread "main" java.util.EmptyStackException
at java.util.Stack.peek(Stack.java:102)
at java.util.Stack.pop(Stack.java:84)
at InfixEvaluation.evaluateInfix(InfixEvaluation.java:42)
at EvaluatorDemo.main(EvaluatorDemo.java:7)

1 个答案:

答案 0 :(得分:0)

你有一个EmptyStackException,这意味着你试图从你的Stack中弹出一个元素,但这个元素是空的。为避免这种情况,您应该使用try catch:

包围所有pop次调用
try {
    operatorStack.pop();
    } catch (EmptyStackException e) {}