基于栈实现带完整括号代数公式计算的异常问题求助
解决带嵌套括号的栈式表达式解析异常问题
我看了你的代码,问题出在berechne方法的循环逻辑上——你现在的逻辑会持续弹出栈元素直到栈大小≤3,这会在处理深层嵌套括号时,错误地把外层的左括号当成操作数/操作符来处理,最终触发NumberFormatException。
问题根源
举个例子,当处理表达式(((6*(4+2))+(5-1))*3)的中间步骤时,栈里会存在外层的左括号。你的循环会在处理完内层括号后继续弹出元素,把外层左括号当作操作符或操作数尝试解析成整数,这自然会抛出转换异常。
正确的逻辑应该是:每个右括号只对应最近的一个左括号,我们只需要计算这个左括号到当前右括号之间的表达式,而不是循环处理整个栈。
修复方案
修改berechne方法,去掉循环,改为精准弹出当前括号内的元素并计算:
public static void berechne() { // 弹出右操作数 Integer operator1 = Integer.parseInt(stack.pop()); // 弹出操作符 String operation = stack.pop(); // 弹出左操作数 Integer operator2 = Integer.parseInt(stack.pop()); // 弹出对应的左括号(清理栈) stack.pop(); int result = 0; // 用switch替代多个if,更清晰高效 switch(operation) { case "+": result = operator2 + operator1; break; case "-": result = operator2 - operator1; break; case "*": result = operator2 * operator1; break; case "/": // 添加除以0的异常处理,避免崩溃 if(operator1 == 0) { throw new ArithmeticException("Division durch Null ist nicht erlaubt!"); } result = operator2 / operator1; break; default: throw new IllegalArgumentException("Unbekannter Operator: " + operation); } // 将计算结果压回栈,供外层表达式使用 stack.push(Integer.toString(result)); }
同时,你的routine方法里调用berechne不需要循环,因为每个右括号只需要触发一次计算:
public static void routine() { stack.push("ende"); while (s.hasNext()) { String temp = s.next(); switch (temp) { case ")": Parser.printStack(); // 保留调试用的栈打印 Parser.berechne(); // 单次调用即可,无需循环 break; default: stack.push(temp); break; } } s.close(); }
修复后的工作流程
以你的测试表达式(((6*(4+2))+(5-1))*3)为例:
- 遇到第一个
)时,只计算(4+2)得到6,压回栈 - 遇到第二个
)时,计算(6*6)得到36,压回栈 - 遇到第三个
)时,计算(5-1)得到4,压回栈 - 遇到第四个
)时,计算(36+4)得到40,压回栈 - 遇到最后一个
)时,计算(40*3)得到120,压回栈 - 最终栈里只剩
ende和120,showErg弹出结果输出
这样就不会再出现类型转换异常,同时能正确处理任意深度的嵌套括号。
额外优化建议
- 把静态的
stack改成实例变量,让Parser类可以被多次复用 - 可以添加输入表达式的参数化支持,而不是硬编码在类里
- 处理表达式时可以先校验括号是否匹配,避免栈空时弹出元素的异常
内容的提问来源于stack exchange,提问作者John_Doe
相关产品推荐
相关产品推荐

