Java如何将字符串形式的数学表达式优雅转为整数输出?
实现Java表达式字符串计算的非递归优雅方案
方案一:利用Java内置ScriptEngine(最简实现)
Java自带的ScriptEngine可以直接解析并执行字符串形式的表达式,完全不用自己写解析逻辑,代码非常简洁:
import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; import javax.script.ScriptException; public class ExpressionEvaluator { public static void main(String[] args) throws ScriptException { String input = "(2+3)*(2+1)"; ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript"); int result = ((Number) engine.eval(input)).intValue(); System.out.println(result); // 输出15 } }
这个方案的优点是无需手动处理运算符优先级、括号嵌套,直接借助JDK内置能力完成,代码量极少,属于最优雅的实现方式。
方案二:迭代式栈实现(手动解析,无递归)
如果不想依赖ScriptEngine,可以用栈结构迭代处理表达式,完全避免递归。核心思路是用两个栈:一个存储操作数,一个存储运算符,遍历表达式时根据运算符优先级和括号做入栈、出栈计算:
import java.util.Stack; public class IterativeExpressionEvaluator { public static int evaluate(String expr) { Stack<Integer> numStack = new Stack<>(); Stack<Character> opStack = new Stack<>(); int n = expr.length(); for (int i = 0; i < n; i++) { char c = expr.charAt(i); // 跳过空格(如果表达式包含空格) if (c == ' ') continue; // 处理多位数数字 if (Character.isDigit(c)) { int num = 0; while (i < n && Character.isDigit(expr.charAt(i))) { num = num * 10 + (expr.charAt(i) - '0'); i++; } numStack.push(num); i--; // 回退一位,抵消循环的自增 } // 左括号直接入栈 else if (c == '(') { opStack.push(c); } // 遇到右括号,计算到左括号为止 else if (c == ')') { while (opStack.peek() != '(') { numStack.push(applyOp(opStack.pop(), numStack.pop(), numStack.pop())); } opStack.pop(); // 弹出左括号 } // 处理运算符,按优先级决定是否先计算 else if (isOperator(c)) { while (!opStack.isEmpty() && hasPrecedence(c, opStack.peek())) { 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(); } // 判断运算符优先级:当前运算符op1优先级是否低于栈顶运算符op2 private static boolean hasPrecedence(char op1, char op2) { if (op2 == '(' || op2 == ')') return false; return (op1 != '*' && op1 != '/') || (op2 != '+' && op2 != '-'); } // 执行运算 private static int applyOp(char op, int b, int a) { switch (op) { case '+': return a + b; case '-': return a - b; case '*': return a * b; case '/': if (b == 0) throw new ArithmeticException("Division by zero"); return a / b; default: return 0; } } // 判断是否为支持的运算符 private static boolean isOperator(char c) { return c == '+' || c == '-' || c == '*' || c == '/'; } public static void main(String[] args) { String input = "(2+3)*(2+1)"; System.out.println(evaluate(input)); // 输出15 } }
这个实现全程用迭代遍历+栈操作,没有任何递归调用,同时支持基本的加减乘除和括号嵌套,逻辑清晰且可控。
内容的提问来源于stack exchange,提问作者Georg
相关产品推荐
相关产品推荐

