В обучении программированию на Android (с использованием Android Studio) Я работаю над базовым калькулятором. Мой метод eval использует алгоритм Shain-yard Dijkstra для синтаксического анализа строкового выражения и вычисления результата. Я получил эту идею от this SO question.Java - Stack.pop не возвращает последний добавленный элемент
Код для моего класса оценщика следующим образом:
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. Когда я извлекаю элементы из каждого стека, я получаю первые элементы, добавленные в каждый стек. У меня создалось впечатление, что стеки были структурой First In Last Out.
Так что я могу делать неправильно? Нужно ли мне каким-то образом отменить каждый стек?
спасибо.
РЕДАКТИРОВАТЬ
Так, например, я вход 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
стек является LIFO см http://docs.oracle.com/javase/ 8/docs/api/java/util/Stack.html –
@RC. - Я с тобой согласен. First In Last Out совпадает с Last In First Out. Однако мои стеки действуют как First In First Out. Я не понимаю, почему они ведут себя таким образом. –
LIFO - это не то же самое, что FILO? Но вы правы, что неважно, используете ли вы lifo или filo. Но это не то же самое. –