令牌和后缀表达式

时间:2017-11-03 03:15:09

标签: java switch-statement token postfix

我目前正在做一个功课,构建一个可以用后缀格式评估字符串表达式的计算器。我已经在我的代码中添加了评估^ * / +的能力 - 但现在我需要添加使用令牌和切换案例执行sin,cos和tan函数的能力。我已经开始为sine添加一个开关,但是我遇到的问题是我总是得到“n”的numberFormatString异常,这是有道理的,因为那将是表达式中的最后一个值。我注意到的是我的代码忽略了“罪”的开关,并转到默认值。

public class Postfix {

    /**
     * Private constructor
     */
    private Postfix() {
        // empty constructor
    }

    /**
     * Evaluates the expression in postfix
     * @param expression
     * @return
     */
    public static double eval(String expression) {
        ArrayDeque<String> operandstack = new ArrayDeque<>();
        StringTokenizer postfixParser = new StringTokenizer(expression, "^*/+-|sin| ", true);

        /**
         * Checks if the token has more tokens
         */
        while (postfixParser.hasMoreTokens()) {
            String token = postfixParser.nextToken().trim();

            if (token.length() > 0) {
                System.out.println(token);
                double operand1 = 0.0;
                double operand2 = 0.0;
                double result = 0.0;

                /**
                 * Evaluates each token
                 */
                switch (token) {
                    /**
                     * Finds the sine value of the operand
                     */
                    case "sin":
                        operand1 = Double.valueOf(operandstack.pop());
                        result = Math.sin(operand1);

                        operandstack.push(String.valueOf(result));
                        break;
                    /**
                     * Creates exponential formula and pushes the result to the stack
                     */
                    case "^":
                        operand1 = Double.valueOf(operandstack.pop());
                        operand2 = Double.valueOf(operandstack.pop());

                        result = Math.pow(operand1, operand2);
                        operandstack.push(String.valueOf(result));
                        break;

                    /**
                     * Creates a multiplication formula and pushes the result to the stack
                     */
                    case "*":
                        operand1 = Double.valueOf(operandstack.pop());
                        operand2 = Double.valueOf(operandstack.pop());

                        result = operand1 * operand2;
                        operandstack.push(String.valueOf(result));
                        break;

                    /**
                     * Creates a division formula and pushes the result to the stack
                     */
                    case "/":
                        operand1 = Double.valueOf(operandstack.pop());
                        operand2 = Double.valueOf(operandstack.pop());

                        result = operand1 / operand2;
                        operandstack.push(String.valueOf(result));
                        break;

                    /**
                     * Creates an addition formula and pushes the result to the stack
                     */
                    case "+":
                        operand1 = Double.valueOf(operandstack.pop());
                        operand2 = Double.valueOf(operandstack.pop());

                        result = operand1 + operand2;
                        operandstack.push(String.valueOf(result));
                        break;

                    /**
                     * Creates a subtraction formula and pushes the result to the stack
                     */
                    case "-":
                        operand1 = Double.valueOf(operandstack.pop());
                        operand2 = Double.valueOf(operandstack.pop());

                        /**
                         * Checks if the operand1 is greater than operand 2, if so subtracts operand1 from operand2
                         */
                        if (operand1 > operand2) {
                            result = operand1 - operand2;
                            operandstack.push(String.valueOf(result));

                            /**
                             * Else subtracts operand2 from operand1
                             */
                        } else {
                            result = operand2 - operand1;
                            operandstack.push(String.valueOf(result));

                        }

                        break;

                    /**
                     *  If no operators, pushes the token to the stack
                     */
                    default:
                        operandstack.push(token);
                        break;

                }

            } else if (token.contains("sin")) {
                double operand1 = Double.valueOf(operandstack.pop());
                double result = Math.sin(operand1);

                operandstack.push(String.valueOf(result));
            }

        }

        /**
         * returns the value from the stack as a double
         */
        return Double.valueOf(operandstack.pop());
    }
}

我的测试代码如下:

double result = Postfix.eval("5.0 sin");
        assertEquals(0.87, result, 0.1);

2 个答案:

答案 0 :(得分:0)

关于您的代码的几条评论。

首先,你的底部其他块是无用的,可以被删除,它永远不会评估,因为token.length将为0,然后字符串肯定不能包含“sin”。采用IntelliJ作为IDE,可以通过静态分析立即发现错误。

您的问题出在您的令牌机中。基本上你需要在空格上进行不同的标记化 - " "

答案 1 :(得分:0)

我能够通过删除&#34; sin&#34;来纠正我的代码。从分界面,并将结果转换为弧度。