You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于栈实现带完整括号代数公式计算的异常问题求助

解决带嵌套括号的栈式表达式解析异常问题

我看了你的代码,问题出在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)为例:

  1. 遇到第一个)时,只计算(4+2)得到6,压回栈
  2. 遇到第二个)时,计算(6*6)得到36,压回栈
  3. 遇到第三个)时,计算(5-1)得到4,压回栈
  4. 遇到第四个)时,计算(36+4)得到40,压回栈
  5. 遇到最后一个)时,计算(40*3)得到120,压回栈
  6. 最终栈里只剩ende和120,showErg弹出结果输出

这样就不会再出现类型转换异常,同时能正确处理任意深度的嵌套括号。

额外优化建议

  • 把静态的stack改成实例变量,让Parser类可以被多次复用
  • 可以添加输入表达式的参数化支持,而不是硬编码在类里
  • 处理表达式时可以先校验括号是否匹配,避免栈空时弹出元素的异常

内容的提问来源于stack exchange,提问作者John_Doe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:36:12