package mathpuzzle.service; import static mathpuzzle.service.PrimarySchoolGenerator.isNumeric; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Stack; /** * 小学数学表达式计算器,用于计算小学级别的数学表达式。 * *

该类使用双栈算法实现中缀表达式的计算,支持加减乘除四则运算和括号。 * 运算符优先级:乘除高于加减,括号具有最高优先级。 * * @author 杨博文 * @version 1.0 * @since 2025 */ public class CaculatePrimary { /** 数字栈,用于存储操作数。 */ private final Stack numStack = new Stack<>(); /** 操作符栈,用于存储运算符和括号。 */ private final Stack opStack = new Stack<>(); /** 运算符优先级映射表,数字越大优先级越高。 */ private final Map precedence = new HashMap<>(); /** * 计算给定的数学表达式。 * *

该方法使用双栈算法计算表达式的值,支持四则运算和括号。 * * @param expression 表达式元素列表,包含数字、运算符和括号 * @return 表达式的计算结果 */ public double caculate(List expression) { precedence.put("+", 1); precedence.put("-", 1); precedence.put("*", 2); precedence.put("/", 2); for (String opOrNum : expression) { if (isNumeric(opOrNum)) { numStack.push(Double.parseDouble(opOrNum)); } else if (opOrNum.equals("(")) { opStack.push(opOrNum); } else if (opOrNum.equals(")")) { while (!opStack.peek().equals("(") && !opStack.isEmpty()) { doCaculte(); } opStack.pop(); } else if (precedence.containsKey(opOrNum)) { while (!opStack.isEmpty() && !opStack.peek().equals("(") && precedence.get(opOrNum) <= precedence.get(opStack.peek())) { doCaculte(); } opStack.push(opOrNum); } } while (!opStack.isEmpty()) { doCaculte(); } return numStack.pop(); } /** * 执行一次基本的二元运算操作。 * *

从数字栈中弹出两个操作数,从操作符栈中弹出一个运算符, * 执行相应的运算,并将结果压入数字栈。 */ public void doCaculte() { String op = opStack.pop(); double num2 = numStack.pop(); double num1 = numStack.pop(); switch (op) { case "+": numStack.push(num1 + num2); break; case "-": numStack.push(num1 - num2); break; case "*": numStack.push(num1 * num2); break; case "/": numStack.push(num1 / num2); break; default: break; } } }