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

如何在Java计算器代码中实现BODMAS/BIDMAS运算规则?

解决方案:支持多运算符连续运算及BODMAS规则的Java Swing计算器

原代码核心问题是仅用单个变量保存前一个数字和运算符,无法记录多步运算状态,也不支持运算符优先级。我们可以通过**双栈(数字栈+运算符栈)**实现需求,同时保留原有UI结构,仅修改运算逻辑部分。

修改后的完整代码

import java.awt.*;
import java.awt.event.*;
import java.util.Stack;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class Calculator implements ActionListener {

    JFrame frame;
    JTextField textfield;
    JButton[] numberButtons = new JButton[10];
    JButton[] functionButtons = new JButton[6];
    JButton addButton, subButton, mulButton, divButton;
    JButton equButton, clrButton;
    JPanel panel;

    Font myFont = new Font("Ink Free", Font.BOLD, 30);

    // 替换原单个变量为双栈,记录运算序列
    Stack<Double> numStack = new Stack<>();
    Stack<Character> opStack = new Stack<>();

    Calculator() {
        // 原UI初始化逻辑保持不变
        frame = new JFrame("Calculator");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(420, 550);
        frame.setLayout(null);

        textfield = new JTextField();
        textfield.setBounds(50, 25, 300, 50);
        textfield.setFont(myFont);

        addButton = new JButton("+");
        subButton = new JButton("-");
        mulButton = new JButton("x");
        divButton = new JButton("÷");
        equButton = new JButton("=");
        clrButton = new JButton("AC");

        functionButtons[0] = addButton;
        functionButtons[1] = subButton;
        functionButtons[2] = mulButton;
        functionButtons[3] = divButton;
        functionButtons[4] = equButton;
        functionButtons[5] = clrButton;

        for (int i = 0; i < 6; i++) {
            functionButtons[i].addActionListener(this);
            functionButtons[i].setFont(myFont);
            functionButtons[i].setFocusable(false);
        }

        for (int i = 0; i < 10; i++) {
            numberButtons[i] = new JButton(String.valueOf(i));
            numberButtons[i].addActionListener(this);
            numberButtons[i].setFont(myFont);
            numberButtons[i].setFocusable(false);
        }

        panel = new JPanel();
        panel.setBounds(50, 100, 300, 300);
        panel.setLayout(new GridLayout(4, 4, 10, 10));

        panel.add(numberButtons[7]);
        panel.add(numberButtons[8]);
        panel.add(numberButtons[9]);
        panel.add(divButton);
        panel.add(numberButtons[4]);
        panel.add(numberButtons[5]);
        panel.add(numberButtons[6]);
        panel.add(mulButton);
        panel.add(numberButtons[1]);
        panel.add(numberButtons[2]);
        panel.add(numberButtons[3]);
        panel.add(subButton);
        panel.add(clrButton);
        panel.add(numberButtons[0]);
        panel.add(equButton);
        panel.add(addButton);

        frame.add(panel);
        frame.add(textfield);
        frame.setVisible(true);
    }

    // 定义运算符优先级:*、÷为2,+、-为1
    private int getPriority(char op) {
        return switch (op) {
            case '*', '/' -> 2;
            case '+', '-' -> 1;
            default -> 0;
        };
    }

    // 封装基础运算逻辑
    private double calculate(double num1, double num2, char op) {
        return switch (op) {
            case '+' -> num1 + num2;
            case '-' -> num1 - num2;
            case '*' -> num1 * num2;
            case '/' -> num2 != 0 ? num1 / num2 : 0; // 简单处理除零情况
            default -> 0;
        };
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        // 数字按钮逻辑保持不变
        for (int i = 0; i < 10; i++) {
            if (e.getSource() == numberButtons[i]) {
                textfield.setText(textfield.getText().concat(String.valueOf(i)));
            }
        }

        // 运算符按钮逻辑:处理优先级并压栈
        if (e.getSource() == addButton || e.getSource() == subButton ||
            e.getSource() == mulButton || e.getSource() == divButton) {
            
            // 将当前输入的数字压入数栈
            if (!textfield.getText().isEmpty()) {
                numStack.push(Double.parseDouble(textfield.getText()));
            }

            char currentOp = e.getSource() == addButton ? '+' :
                             e.getSource() == subButton ? '-' :
                             e.getSource() == mulButton ? '*' : '/';

            // 先计算栈中优先级更高或相等的运算符,符合BODMAS规则
            while (!opStack.isEmpty() && getPriority(opStack.peek()) >= getPriority(currentOp)) {
                double num2 = numStack.pop();
                double num1 = numStack.pop();
                char op = opStack.pop();
                numStack.push(calculate(num1, num2, op));
            }

            opStack.push(currentOp);
            textfield.setText("");
        }

        // 等于号按钮逻辑:计算所有剩余运算
        if (e.getSource() == equButton) {
            if (!textfield.getText().isEmpty()) {
                numStack.push(Double.parseDouble(textfield.getText()));
            }

            // 依次处理栈中所有剩余运算符
            while (!opStack.isEmpty()) {
                double num2 = numStack.pop();
                double num1 = numStack.pop();
                char op = opStack.pop();
                numStack.push(calculate(num1, num2, op));
            }

            // 显示结果并保留到栈中,支持后续连续运算
            if (!numStack.isEmpty()) {
                double result = numStack.pop();
                textfield.setText(String.valueOf(result));
                numStack.push(result);
            }
        }

        // 清空按钮逻辑:重置栈和输入框
        if (e.getSource() == clrButton) {
            textfield.setText("");
            numStack.clear();
            opStack.clear();
        }
    }

    public static void main(String[] args) {
        new Calculator();
    }
}

关键修改说明

  1. 双栈替代单变量:用numStack保存所有输入数字,opStack保存运算符,完整记录运算序列,解决原代码无法追踪多步运算的问题。
  2. 优先级处理:通过getPriority定义运算符优先级,输入新运算符时先计算栈中优先级更高或相等的运算,严格遵循BODMAS规则。
  3. 连续运算支持:点击等于号后,结果会重新压入数字栈,可直接继续输入运算符进行后续运算(例如2x5/2=得到5后,继续+3=可得到8)。
  4. 逻辑解耦:将运算逻辑封装到calculate方法中,代码更易维护。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 11:02:03