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

C# 如何实现字符串格式数学表达式的数值计算功能?

C# 字符串数学表达式计算实现方案

你可以根据场景选择以下两种实现方案:

方案1:使用成熟第三方库(推荐,快速落地)

可以使用NCalc库,支持绝大多数常用运算符(加减乘除、幂运算、取模、括号、自定义函数、变量等),不需要自己处理复杂的运算符优先级、语法解析逻辑。

使用步骤:

  • 通过NuGet安装NCalc包
  • 实现Calculate方法代码如下:
using NCalc;

public static object Calculate(string input)
{
    // NCalc默认^为异或运算符,如需用^表示幂运算,提前替换为**即可
    input = input.Replace("^", "**");
    Expression expression = new Expression(input);
    if (expression.HasErrors())
    {
        throw new InvalidOperationException($"表达式解析错误:{expression.Error}");
    }
    return expression.Evaluate();
}

你给出的示例输入"2+2+2+2*5^2/2"调用方法后返回结果为31,符合预期。

方案2:手动实现表达式解析(适合不允许引入第三方依赖的场景)

核心逻辑是先把中缀表达式转换为逆波兰(后缀)表达式,再计算后缀表达式结果,可灵活扩展支持自定义运算符。

示例实现代码:

public static double Calculate(string input)
{
    // 预处理:去掉所有空格
    input = input.Replace(" ", "");
    var postfix = InfixToPostfix(input);
    return EvaluatePostfix(postfix);
}

// 中缀表达式转后缀表达式
private static List<string> InfixToPostfix(string infix)
{
    List<string> postfix = new List<string>();
    Stack<char> opStack = new Stack<char>();
    Dictionary<char, int> priority = new Dictionary<char, int>
    {
        {'+', 1}, {'-', 1},
        {'*', 2}, {'/', 2},
        {'^', 3},
        {'(', 0}
    };
    int i = 0;
    while (i < infix.Length)
    {
        // 处理数字(含小数)
        if (char.IsDigit(infix[i]) || infix[i] == '.')
        {
            string num = "";
            while (i < infix.Length && (char.IsDigit(infix[i]) || infix[i] == '.'))
            {
                num += infix[i];
                i++;
            }
            postfix.Add(num);
        }
        // 左括号直接入栈
        else if (infix[i] == '(')
        {
            opStack.Push(infix[i]);
            i++;
        }
        // 右括号弹出运算符直到遇到左括号
        else if (infix[i] == ')')
        {
            while (opStack.Peek() != '(')
            {
                postfix.Add(opStack.Pop().ToString());
            }
            opStack.Pop(); // 丢弃左括号
            i++;
        }
        // 处理普通运算符
        else
        {
            while (opStack.Count > 0 && priority[opStack.Peek()] >= priority[infix[i]])
            {
                postfix.Add(opStack.Pop().ToString());
            }
            opStack.Push(infix[i]);
            i++;
        }
    }
    // 弹出栈内剩余运算符
    while (opStack.Count > 0)
    {
        postfix.Add(opStack.Pop().ToString());
    }
    return postfix;
}

// 计算后缀表达式结果
private static double EvaluatePostfix(List<string> postfix)
{
    Stack<double> stack = new Stack<double>();
    foreach (var token in postfix)
    {
        if (double.TryParse(token, out double num))
        {
            stack.Push(num);
        }
        else
        {
            double b = stack.Pop();
            double a = stack.Pop();
            switch (token)
            {
                case "+": stack.Push(a + b); break;
                case "-": stack.Push(a - b); break;
                case "*": stack.Push(a * b); break;
                case "/": stack.Push(a / b); break;
                case "^": stack.Push(Math.Pow(a, b)); break;
            }
        }
    }
    return stack.Pop();
}

注:上述代码默认支持整数、小数、加减乘除、幂运算、括号运算,可根据需求扩展运算符和自定义函数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.18 07:24:10