在自学 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/