Я вижу, что вы пытаетесь сделать сейчас. Давайте сначала посмотрим на ваш код для оценки выражений postfix (второй блок кода).
Ваше вычитание задом наперед. У вас есть:
else if (next.equals("-")) {
stack.push(String.valueOf((Integer.parseInt(stack.pop())) - (Integer.parseInt(stack.pop()))));
Рассмотрим постфиксное выражение 2 1 -
. Это соответствует инфиксному выражению 2 - 1
. Поэтому, когда вы оцениваете постфикс, вы нажимаете 2 и 1, а затем видите оператора. Ваш код выскакивает 1, всплывает 2 и выполняет 1 - 2
. Но это должно было выполнить 2 - 1
.
Вам необходимо изменить порядок операндов в вашем вычитании. То есть:
op1 = stack.pop();
op2 = stack.pop();
stack.push(op2 - op1);
Вы делаете ту же ошибку в своем коде, который читает префиксные выражения в обратном порядке.
Давайте возьмем префиксное выражение + - 10 1 2
и преобразуем его в постфикс.
input action operand stack
2 push 2
1 push 1, 2
10 push 10, 1, 2
- evaluate 9
+ evaluate 11
Но ваш код сделает 1-10
, чтобы получить -9
.
Также обратите внимание, что префиксное выражение + - 2 5 8
соответствует инфиксному выражению 2-5+8
. Постфиксное выражение 2 5 8 + -
соответствует инфиксному выражению 2-(5+8)
.
Выражение постфикса, соответствующее + - 2 5 8
, равно 2 5 - 8 +
.
Чтение в обратном направлении
Я на самом деле не программист на Java, поэтому кто-то может исправить меня, если я ошибаюсь. Но из того, что я прочитал (см., Например, Можете ли вы переместить сканер в какое-либо место в файле или отсканировать назад? ), вы не можете использовать Scanner
для чтения в обратном направлении.
Я хотел бы предложить вам прочитать строку с самого начала и поместить каждый токен в стек. Затем прочитайте из стека в вашем цикле. Что-то вроде:
Stack<string> inputStack = new Stack<string>();
Scanner sc = new Scanner(System.in);
while (sc.hasNext()) {
inputStack.push(sc.next());
}
Жетоны теперь находятся на inputStack
в обратном порядке. Вы можете читать их задом наперед, выталкивая их из стека.
while (!inputStack.empty()) {
String next = inputStack.pop();
System.out.println(next); // just to make sure it's reading correctly
if (!isOperator(next)) {
...
}
// ... rest of your code goes here
}
Как я уже сказал, я на самом деле не программист на Java, и у меня здесь не настроена среда разработки Java, поэтому я не могу гарантировать, что это сработает, но похоже, что должно.