Java中如何计算包含四则运算的数字字符串的算术运算结果
Java 四则运算字符串的计算方案
你需要计算String num = "42*65+223-55/23";这类包含加减乘除的字符串运算结果,下面是两种常用实现方式:
方案1:使用JDK内置脚本引擎(最简实现)
这个方法不需要引入第三方依赖,直接调用JDK自带的ScriptEngine即可完成计算,代码示例:
import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; import javax.script.ScriptException; public class CalcTest { public static void main(String[] args) throws ScriptException { String num = "42*65+223-55/23"; ScriptEngineManager manager = new ScriptEngineManager(); ScriptEngine engine = manager.getEngineByName("JavaScript"); // 执行运算 Object result = engine.eval(num); System.out.println(result); // 输出约2950.608695652174 } }
注意事项:
- JDK8及之前版本默认内置Nashorn JS引擎,JDK11及以上版本如果移除了Nashorn,可引入
org.openjdk.nashorn:nashorn-core依赖适配,或者切换到groovy等其他脚本引擎- 生产环境使用需做好输入校验,避免传入恶意脚本执行风险
方案2:手动实现双栈逻辑(无依赖、安全可控)
如果不想引入脚本引擎,也可以自己通过双栈逻辑实现四则运算,自动处理乘除优先于加减的规则,核心逻辑如下:
- 用两个栈,分别存储数字和运算符
- 遍历字符串,拆分出数字和运算符
- 遇到运算符时,先把栈中优先级 >= 当前运算符的运算先执行,再把当前运算符压栈
- 遍历结束后执行栈中剩余的所有运算,得到最终结果
核心代码示例:
import java.util.Deque; import java.util.LinkedList; public class ManualCalc { public static void main(String[] args) { String num = "42*65+223-55/23"; System.out.println(calculate(num)); // 输出约2950.608695652174 } private static double calculate(String s) { Deque<Double> numStack = new LinkedList<>(); Deque<Character> opStack = new LinkedList<>(); int n = s.length(); int i = 0; while (i < n) { char c = s.charAt(i); if (Character.isDigit(c)) { // 拆分多位数字 double num = 0; while (i < n && Character.isDigit(s.charAt(i))) { num = num * 10 + (s.charAt(i) - '0'); i++; } numStack.push(num); } else { // 处理运算符 while (!opStack.isEmpty() && getPriority(opStack.peek()) >= getPriority(c)) { calc(numStack, opStack); } opStack.push(c); i++; } } // 处理剩余运算 while (!opStack.isEmpty()) { calc(numStack, opStack); } return numStack.pop(); } // 获取运算符优先级 private static int getPriority(char op) { return op == '*' || op == '/' ? 2 : 1; } // 执行单次运算 private static void calc(Deque<Double> numStack, Deque<Character> opStack) { double b = numStack.pop(); double a = numStack.pop(); char op = opStack.pop(); double res = switch (op) { case '+' -> a + b; case '-' -> a - b; case '*' -> a * b; case '/' -> a / b; default -> throw new IllegalArgumentException("非法运算符:" + op); }; numStack.push(res); } }
补充:如果需要支持括号、小数、正负号,只需要在上述逻辑基础上增加对应的字符判断分支即可。
内容的提问来源于stack exchange,提问作者Abdul Musavveer Alji
相关产品推荐
相关产品推荐

