当前的任务是评估以
格式给出的后缀表达式,返回答案为
String
。该表达式具有每个元素由单个空格分隔并且只有 4 个运算符
Long
的特点。例如。
+, -, *, \
"2 3 9 4 / + *"
问题是我的代码遇到了
EmptyStackException
:
public static long evaluate(String s) {
String[] byUnit = s.split("\\s");
long total = 0L;
boolean initialAssign = true;
Stack<Long> stack = new Stack<Long>();
for(String unit: byUnit) {
try {
stack.push(Long.parseLong(unit));
//System.out.println(stack.peek());
continue;
}catch(Exception e) {
if(initialAssign) {
long temp = stack.pop();
total = stack.pop();
stack.push(temp);
initialAssign = false;
}
//System.out.println(stack.peek());
switch(unit) {
case "+":
total += stack.pop();
//System.out.println(stack.peek());
case "-":
total -= stack.pop();
case "*":
total *= stack.pop();
case "/":
total /= stack.pop();
}
}
}
return total;
}
错误发生在以下代码行:
total *= stack.pop();
Exception in thread "main" java.util.EmptyStackException
编辑:
if(initialAssign) {
long temp = stack.pop();
total = stack.pop();
stack.push(temp);
initialAssign = false;
}
上面的代码为总计分配了正确的初始值。由于表达式是从左到右计算的,因此在
"2 3 9 4 / + *"
中,total
应从 9
开始,因为我们想要 9/4 而不是 4/9 (total /= stack.pop()
)。然而,当程序遇到第一个运算符时,stack.pop()
将根据LIFO输出4
。因此,首先将 pop()
、4
放入临时变量中,然后将 pop()
分配给 total = 9
和 push(temp = 4)
回堆栈,这样就不会丢失。
布尔值
initialAssign
确保它仅发生在第一个运算符上,因为后续的总计值将遵循从左到右的评估。
但是,我使用
stack.peek()
检查了循环中的 3 个不同点,并且堆栈不为空。此外,我使用 stack.isEmpty()
(不在上面的代码中)进一步检查,它确实不为空。为什么当涉及到 *
运算符时,堆栈会突然变空? 2
应该仍然存在于堆栈中。
首先,不要因为你的令牌是一个操作而让你的程序抛出异常
String
。异常应该是异常状态,而进行操作根本不是异常。这是一个修复:
import java.util.*;
public class Main {
public static void main(String[] args) {
System.out.println(evaluate("2 3 9 4 / + *"));
}
public static long evaluate(String s) {
String[] byUnit = s.split("\\s");
long total = 0L;
boolean initialAssign = true;
Stack<Long> stack = new Stack<Long>();
for(String unit: byUnit) {
long earlyTotal = total;
long pop = -1;
try {
switch (unit.charAt(0)) {
case '+':
if (initialAssign) {
total = stack.pop();
initialAssign = false;
}
total += stack.pop();
break;
case '-':
if (initialAssign) {
total = stack.pop();
initialAssign = false;
}
total -= stack.pop();
break;
case '*':
if (initialAssign) {
total = stack.pop();
initialAssign = false;
}
total *= stack.pop();
break;
case '/':
if (initialAssign) {
total = stack.pop();
initialAssign = false;
}
total /= stack.pop();
break;
default:
stack.push(Long.parseLong(unit));
}
System.out.println(total);
}catch(Exception e) {
//handle the exception
System.out.println(e.toString());
}
}
return total;
}
}
我不确定操作和操作数应该朝哪个方向求值,因此,如果从右到左操作数求值和从左到右运算符求值不适合您的场景,请随时修复它或发表评论.