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

如何在Java中实现支持运算优先级与括号的计算器?

实现支持括号与运算优先级的计算器

你现在要做的是表达式求值器,和基础版的两数运算完全不同,核心要解决的是运算符优先级和括号嵌套的问题。下面给你两种适合新手理解的实现思路:

方法一:后缀表达式(逆波兰表达式)转换法

这是经典的表达式求值方案,分两步走:把用户输入的中缀表达式(比如20/((10+5)*2))转换成后缀表达式,再计算后缀表达式的结果。

步骤1:中缀转后缀

遵循以下规则处理每个字符:

  • 遇到数字直接加入输出列表
  • 遇到运算符(+、-、*、/):
    • 弹出栈中所有优先级大于等于当前运算符的运算符到输出列表,再把当前运算符压入栈
    • 优先级规则:*、/ > +、-
  • 遇到左括号(:直接压入栈
  • 遇到右括号):弹出栈中运算符到输出列表,直到碰到左括号(,弹出左括号但不加入输出列表
  • 遍历完所有字符后,把栈中剩余的运算符全部弹出到输出列表

以你的例子20/((10+5)*2)为例,转换后的后缀表达式是:20 10 5 + 2 * /

步骤2:计算后缀表达式

遍历后缀表达式,用栈处理:

  • 遇到数字就压入栈
  • 遇到运算符,弹出栈顶两个数(注意:后弹出的是左操作数),用运算符计算后把结果压回栈
  • 遍历结束后,栈中剩余的唯一值就是计算结果

方法二:递归下降解析法

这种方法更贴近语法逻辑,把表达式按优先级拆分成不同的“语法单元”,用递归处理嵌套的括号,适合新手写代码实现。

核心思路

把表达式拆解为三个层级(优先级从低到高):

  1. 表达式(Expression):由多个项(Term)通过加减运算符连接而成
  2. 项(Term):由多个因子(Factor)通过乘除运算符连接而成
  3. 因子(Factor):要么是数字,要么是括号包裹的表达式(递归处理括号内的内容)

示例Java代码

import java.util.Scanner;

public class AdvancedCalculator {
    private static Scanner scanner;
    private static int currentPos;
    private static String inputExpr;

    public static void main(String[] args) {
        scanner = new Scanner(System.in);
        System.out.println("请输入运算表达式:");
        inputExpr = scanner.nextLine().replaceAll("\\s", ""); // 移除所有空格
        currentPos = 0;

        try {
            double result = parseExpression();
            System.out.println("计算结果:" + result);
        } catch (Exception e) {
            System.out.println("错误:" + e.getMessage());
        }
    }

    // 处理加减运算(最低优先级)
    private static double parseExpression() {
        double result = parseTerm();
        while (currentPos < inputExpr.length()) {
            char op = inputExpr.charAt(currentPos);
            if (op == '+' || op == '-') {
                currentPos++;
                double termValue = parseTerm();
                if (op == '+') {
                    result += termValue;
                } else {
                    result -= termValue;
                }
            } else {
                break;
            }
        }
        return result;
    }

    // 处理乘除运算(中等优先级)
    private static double parseTerm() {
        double result = parseFactor();
        while (currentPos < inputExpr.length()) {
            char op = inputExpr.charAt(currentPos);
            if (op == '*' || op == '/') {
                currentPos++;
                double factorValue = parseFactor();
                if (op == '*') {
                    result *= factorValue;
                } else {
                    if (factorValue == 0) {
                        throw new ArithmeticException("除数不能为0");
                    }
                    result /= factorValue;
                }
            } else {
                break;
            }
        }
        return result;
    }

    // 处理数字和括号(最高优先级)
    private static double parseFactor() {
        char currentChar = inputExpr.charAt(currentPos);
        // 处理括号:递归解析括号内的表达式
        if (currentChar == '(') {
            currentPos++;
            double result = parseExpression();
            if (currentPos >= inputExpr.length() || inputExpr.charAt(currentPos) != ')') {
                throw new IllegalArgumentException("表达式缺少右括号");
            }
            currentPos++;
            return result;
        }
        // 处理数字(支持小数)
        else if (Character.isDigit(currentChar) || currentChar == '.') {
            int startPos = currentPos;
            while (currentPos < inputExpr.length() && (Character.isDigit(inputExpr.charAt(currentPos)) || inputExpr.charAt(currentPos) == '.')) {
                currentPos++;
            }
            return Double.parseDouble(inputExpr.substring(startPos, currentPos));
        } else {
            throw new IllegalArgumentException("无效字符:" + currentChar);
        }
    }
}

代码说明

  • parseFactor遇到括号时,会递归调用parseExpression处理括号内的内容,自动解决嵌套括号的问题
  • parseExpression依赖parseTerm,parseTerm依赖parseFactor,保证了乘除运算先于加减运算执行
  • 代码还处理了基本的错误情况:缺少括号、除数为0、无效字符

新手注意事项

  • 先处理输入中的空格:用户输入可能带空格,要先移除或者忽略
  • 错误处理:实际使用中要考虑各种非法输入(比如字母、不匹配的括号、除0)
  • 扩展功能:如果要支持更多运算符(比如^幂运算),只需要调整优先级规则和对应的解析逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 14:30:36