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

Java简易计算器开发求助:无法实现功能及MDAS优先级规则

解决Java简易计算器的MDAS优先级与运行问题

嘿,作为编程新手搞计算器确实容易在运算符优先级和输入解析上卡壳,我来帮你一步步搞定这个问题!

首先,你提到要遵循MDAS规则(乘除优先于加减),同时实现输入1 + 1输出2,核心难点在于不能按输入顺序直接计算,得先处理乘除,再处理加减。下面是具体的解决方案:

1. 核心思路:双栈法处理优先级

最经典的表达式求值方法就是用两个栈:一个存数字,一个存运算符。逻辑大概是这样:

  • 遇到数字就压入数字栈
  • 遇到运算符时,和栈顶的运算符比较优先级:
    • 如果当前运算符优先级低于或等于栈顶,就弹出栈顶运算符和两个数字计算,结果压回数字栈
    • 重复这个过程直到栈顶运算符优先级更低,再把当前运算符压入栈
  • 最后把栈里剩下的运算符依次计算,数字栈的最后一个元素就是结果

2. 完整代码实现

下面是包含输入解析、优先级处理和计算的完整代码,你可以直接测试:

import java.util.Scanner;
import java.util.Stack;

public class SimpleCalculator {

    // 定义运算符优先级:乘除>加减
    private static int getPriority(char op) {
        switch (op) {
            case '+':
            case '-':
                return 1;
            case '*':
            case '/':
                return 2;
            default:
                return 0;
        }
    }

    // 执行运算:注意栈的后进先出,b是右操作数,a是左操作数
    private static double applyOp(char op, double b, double a) {
        switch (op) {
            case '+':
                return a + b;
            case '-':
                return a - b;
            case '*':
                return a * b;
            case '/':
                if (b == 0) {
                    throw new ArithmeticException("不能除以零");
                }
                return a / b;
            default:
                return 0;
        }
    }

    // 解析并计算表达式
    private static double calculate(String expression) {
        Stack<Double> numStack = new Stack<>();
        Stack<Character> opStack = new Stack<>();

        for (int i = 0; i < expression.length(); i++) {
            char c = expression.charAt(i);

            // 跳过输入中的空格
            if (Character.isWhitespace(c)) {
                continue;
            }

            // 处理数字(包括多位数和小数)
            if (Character.isDigit(c) || c == '.') {
                StringBuilder numStr = new StringBuilder();
                // 把连续的数字/小数点拼接成完整数字
                while (i < expression.length() && (Character.isDigit(expression.charAt(i)) || expression.charAt(i) == '.')) {
                    numStr.append(expression.charAt(i));
                    i++;
                }
                i--; // 回退一位,因为循环里i已经自增了
                numStack.push(Double.parseDouble(numStr.toString()));
                // 这里添加你需要的调试输出,匹配示例格式
                System.out.println("index= " + i + " " + numStr);
            }
            // 处理左括号(可选支持括号运算)
            else if (c == '(') {
                opStack.push(c);
            }
            // 处理右括号:计算到左括号为止
            else if (c == ')') {
                while (opStack.peek() != '(') {
                    numStack.push(applyOp(opStack.pop(), numStack.pop(), numStack.pop()));
                }
                opStack.pop(); // 弹出左括号
            }
            // 处理运算符
            else {
                while (!opStack.isEmpty() && getPriority(opStack.peek()) >= getPriority(c)) {
                    numStack.push(applyOp(opStack.pop(), numStack.pop(), numStack.pop()));
                }
                opStack.push(c);
            }
        }

        // 处理栈中剩余的运算符
        while (!opStack.isEmpty()) {
            numStack.push(applyOp(opStack.pop(), numStack.pop(), numStack.pop()));
        }

        return numStack.pop();
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.print("Enter: ");
        String input = scanner.nextLine().replace("=", ""); // 去掉输入里的=号

        try {
            double result = calculate(input);
            System.out.println(result);
        } catch (Exception e) {
            System.out.println("输入有误:" + e.getMessage());
        }
        scanner.close();
    }
}

3. 关键细节说明

  • 优先级判断:getPriority方法给乘除赋值2,加减赋值1,确保乘除先被计算
  • 数字解析:用StringBuilder拼接连续的数字和小数点,支持多位数和小数
  • 操作数顺序:栈是后进先出,所以弹出的第一个数字是右操作数,第二个是左操作数(比如计算a - b,弹出的顺序是b、a)
  • 调试输出:代码里已经添加了类似你示例的index= X 数字输出,完全匹配你的预期格式

4. 测试示例

输入2+1=,程序会输出:

Enter: 2+1=
index= 0 2
index= 2 1
3.0

输入1+2*3=,会正确输出7.0(严格遵循MDAS规则)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 11:33:24