如何在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(); } }
关键修改说明
- 双栈替代单变量:用
numStack保存所有输入数字,opStack保存运算符,完整记录运算序列,解决原代码无法追踪多步运算的问题。 - 优先级处理:通过
getPriority定义运算符优先级,输入新运算符时先计算栈中优先级更高或相等的运算,严格遵循BODMAS规则。 - 连续运算支持:点击等于号后,结果会重新压入数字栈,可直接继续输入运算符进行后续运算(例如
2x5/2=得到5后,继续+3=可得到8)。 - 逻辑解耦:将运算逻辑封装到
calculate方法中,代码更易维护。
内容的提问来源于stack exchange,提问作者Deniz Gok
相关产品推荐
相关产品推荐

