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

如何计算字符串类型的数学表达式结果?代码示例求助

如何计算字符串类型的数学表达式值

你之前尝试用Double.parseDouble()失败,是因为这个方法只能解析纯数字格式的字符串,带+、*这类运算符的字符串不属于合法浮点数,会直接抛出NumberFormatException。

下面给你两种可行的实现方案:

方案一:使用Java自带的ScriptEngine(推荐)

Java内置了脚本引擎,可以直接执行字符串形式的表达式,支持运算符优先级、括号等常见语法,无需额外依赖:

import javax.script.ScriptEngineManager;
import javax.script.ScriptEngine;
import javax.script.ScriptException;

// 嵌入到你的代码逻辑中
String x = dis.getText(); // 示例值:"2+3*4"
ScriptEngineManager manager = new ScriptEngineManager();
// 调用JavaScript引擎计算表达式
ScriptEngine engine = manager.getEngineByName("JavaScript");

try {
    // 执行表达式并获取结果
    Object result = engine.eval(x);
    dis.setText("Result :" + result); // 输出:Result :14
} catch (ScriptException e) {
    // 处理表达式不合法的情况
    dis.setText("无效的表达式");
    e.printStackTrace();
}

这个方案的优势:

  • 无需自己处理运算符优先级、语法解析等复杂逻辑
  • 支持绝大多数常见数学运算(加减乘除、取模、幂运算、括号嵌套等)

注意:如果应用会接收不可控的用户输入,要警惕脚本注入风险(比如输入恶意JavaScript代码),这种场景建议用方案二。

方案二:手动实现表达式解析(适合学习或定制需求)

如果不想依赖脚本引擎,可以自己实现简单的表达式计算器,核心思路是通过栈结构处理运算符优先级:

  1. 将中缀表达式(如2+3*4)转换为后缀表达式(逆波兰表达式:2 3 4 * +)
  2. 遍历后缀表达式,用栈计算最终结果

示例简化版代码(仅支持加减乘除):

import java.util.Stack;

public class ExpressionCalculator {
    public static double calculate(String expr) throws Exception {
        Stack<Double> numStack = new Stack<>();
        Stack<Character> opStack = new Stack<>();
        int i = 0;
        while (i < expr.length()) {
            char c = expr.charAt(i);
            if (Character.isDigit(c) || c == '.') {
                // 解析数字(支持小数)
                StringBuilder sb = new StringBuilder();
                while (i < expr.length() && (Character.isDigit(expr.charAt(i)) || expr.charAt(i) == '.')) {
                    sb.append(expr.charAt(i++));
                }
                numStack.push(Double.parseDouble(sb.toString()));
            } else if (isOperator(c)) {
                // 处理运算符优先级,栈顶优先级高则先计算
                while (!opStack.isEmpty() && getPriority(opStack.peek()) >= getPriority(c)) {
                    numStack.push(compute(numStack.pop(), numStack.pop(), opStack.pop()));
                }
                opStack.push(c);
                i++;
            } else {
                throw new Exception("无效字符:" + c);
            }
        }
        // 处理剩余运算符
        while (!opStack.isEmpty()) {
            numStack.push(compute(numStack.pop(), numStack.pop(), opStack.pop()));
        }
        return numStack.pop();
    }

    private static boolean isOperator(char c) {
        return c == '+' || c == '-' || c == '*' || c == '/';
    }

    private static int getPriority(char op) {
        return op == '*' || op == '/' ? 2 : 1;
    }

    private static double compute(double b, double a, char op) {
        switch (op) {
            case '+': return a + b;
            case '-': return a - b;
            case '*': return a * b;
            case '/': 
                if (b == 0) throw new ArithmeticException("除数不能为0");
                return a / b;
            default: throw new IllegalArgumentException("未知运算符:" + op);
        }
    }
}

使用方式:

String x = dis.getText();
try {
    double result = ExpressionCalculator.calculate(x);
    dis.setText("Result :" + result);
} catch (Exception e) {
    dis.setText("计算出错:" + e.getMessage());
    e.printStackTrace();
}

这个方案适合需要高度定制运算规则的场景,但需要自己处理更多边界情况(比如括号、负数、运算符优先级扩展等)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 22:38:15