Java - Stack.pop 不返回最后添加的项目

标签 java android

在自学 Android 编程(使用 Android Studio)时,我正在开发一个基本的计算器应用程序。我的 eval 方法使用 Dijkstra 的分流场算法来解析字符串表达式并计算结果。我从 this SO question 得到了这个想法.

我的 Evaluator 类的代码如下:

class Evaluator {
    private static Evaluator instance = new Evaluator();

    private Stack< String > mOperators;
    private Stack< Double > mOperands;

    public static Evaluator getInstance() {
        return instance;
    }

    private Evaluator() {
        mOperands = new Stack< Double >();
        mOperators = new Stack< String >();
    }

    public Double eval( String expression ) {
        Stack stack = convertExpressionToStack( expression );
        buildOperationStacks( stack );
        return doEval();
    }

    private Double doEval() {
        while ( !mOperators.isEmpty() ) {
            String op = mOperators.pop();
            Double v = mOperands.pop();

            switch ( op ) {
                case "+":
                    v = mOperands.pop() + v;
                    break;
                case "-":
                    v = mOperands.pop() - v;
                    break;
                case "*":
                    v = mOperands.pop() * v;
                    break;
                case "/":
                    v = mOperands.pop() / v;
                    break;
            }

            mOperands.push( v );
        }

        return mOperands.pop();
    }

    private void buildOperationStacks( Stack stack ) {
        while ( !stack.isEmpty() ) {
            String s = ( String ) stack.pop();

            switch ( s ) {
                case "+":
                case "-":
                case "*":
                case "x":
                case "X":
                case "/":
                case "÷":
                    if ( s.equals( "x" ) || s.equals( "X" ) ) {
                        s = "*";
                    } else if ( s.equals( "÷" ) ) {
                        s = "/";
                    }

                    mOperators.push( s );
                    break;
                default:
                    try {
                        if ( !stack.isEmpty() && stack.peek().equals  ( "." ) ) {
                            s += stack.pop();
                            s += stack.pop();
                        }

                        mOperands.push( Double.parseDouble( s ) );
                    } catch ( Exception e ) {
                        Log.e( "Error", e.getMessage() );
                    }
            }
        }
    }

    private Stack convertExpressionToStack( String expression ) {
        Stack< String > s = new Stack< String >();

        for ( char c : expression.toCharArray() ) {
            s.push( String.valueOf( c ) );
        }

        return s;
    }
}

所以我的问题出在 doEval 方法中。当我从每个堆栈中弹出元素时,我将第一个元素添加到每个堆栈中。我的印象是堆栈是先进后出结构。

那么我可能做错了什么?我需要以某种方式反转每个堆栈吗?

谢谢。

编辑

例如,我输入5+3*2。我希望执行是

pass 1: value1 = 2, Operator1 = *, value2 = 3 result = 6
pass 2: Value1 = 6 (result of pass 1) Operator1 = +, value2 = 5 result = 11

但是,当我调试这个时,我看到:

pass 1: value1 = 5, Operator1 = +, value2 = 3, result = 8
pass 2: value1 = 8 (result of pass 1), operator1 = *, value2 = 2, result = 16

最佳答案

您的 convertExpressionToStack() 方法正在以正确的顺序构建操作数堆栈,然后您的 buildOperstionStack() 方法通过弹出一个操作数堆栈并推送另一个操作数堆栈来反转它.

无论如何,您实际上并不需要第二种方法:只需更改计算方法以将 x 理解为乘法等。

关于Java - Stack.pop 不返回最后添加的项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39920885/

相关文章:

android - FusedLocationApi.getLastLocation 始终为空

android - 在 Android Studio 中运行单元测试时,类覆盖率和行覆盖率有什么区别?

安卓。如何更改选项卡内的 Activity

java - 保持持久的http连接

Java 8 默认方法的可读性

java - 在 Spring Boot 客户端中接收 Flux

java - 通用方法与通配符 - 编译错误

android - 获取元素 Jetpack Compose 的高度

java - java 两个特定单词之间的文本

java - 为什么对象返回空?安卓。改造2