解析数学表达式

时间:2010-10-19 21:19:14

标签: c# .net c#-4.0

是否有一种简单的方法可以解析表示为字符串的简单数学表达式,例如(x +(2 * x)/(1-x)),为x提供值,并获得结果?

我在几个在线示例中查看了VSAEngine,但是,我收到一条警告,说这个程序集已被弃用而不能使用它。

如果它有任何差异,我使用的是.NET 4.0。

9 个答案:

答案 0 :(得分:10)

我强烈建议不要在特制的数学评估器上选择现有的通用表达式求值程序。这样做的原因是表达式评估者不仅限于数学。一个聪明的人可以使用它在框架中创建任何类型的实例并调用该类型的任何方法,这将允许他做一些明显不受欢迎的事情。例如:new System.Net.WebClient().DownloadFile("illegalchildpornurl", "C:\openme.gif")会在大多数情况下评估得很好,并且只会听到它的声音(同时让你成为重罪犯)。

这并不意味着不要寻找已经写好的东西。这只是意味着要小心。你想要一个做数学,只做数学的人。已经存在的大部分内容都不那么挑剔。

答案 1 :(得分:8)

我最近使用的是mXparser,它是一个数学解析器库。它为您提供了很多灵活性,例如变量,函数,常量,运算符。您将在下面找到一些使用示例:

示例1 - 简单公式

Expression e = new Expression("1 + pi");
double v = e.calculate();

示例2 - 包含变量,函数等的公式

Argument x = new Argument("x = 2");
Constant a = new Constant("a = sin(10)");
Function f = new Function("f(t) = t^2");
Expression e = new Expression("2*x + a - f(10)", x, a, f);
double v = e.calculate();

https://mxparser.codeplex.com/

http://mathparser.org/

发现 - 您可以通过由mXparser提供支持的Scalar Calculator应用程序尝试语法(并查看用例)。

祝你好运

祝你好运

答案 2 :(得分:5)

您可以尝试使用DataTable.Compute

相关的是DataColumn.Expression

另请查看:Doing math in vb.net like Eval in javascript

注意:我自己没有使用过这些。

答案 3 :(得分:3)

我还要看看Jace(https://github.com/pieterderycke/Jace)。 Jace是一个高性能的数学解析器和计算引擎,支持所有.NET风格(.NET 4.x,Windows Phone,Windows Store,...)。 Jace也可以通过NuGet获得:https://www.nuget.org/packages/Jace

答案 4 :(得分:2)

这是一种方法。此代码是用Java编写的。请注意,它现在不处理负数,但您可以添加它。

public class ExpressionParser {
public double eval(String exp, Map<String, Double> vars){
    int bracketCounter = 0;
    int operatorIndex = -1;

    for(int i=0; i<exp.length(); i++){
        char c = exp.charAt(i);
        if(c == '(') bracketCounter++;
        else if(c == ')') bracketCounter--;
        else if((c == '+' || c == '-') && bracketCounter == 0){
            operatorIndex = i;
            break;
        }
        else if((c == '*' || c == '/') && bracketCounter == 0 && operatorIndex < 0){
            operatorIndex = i;
        }
    }
    if(operatorIndex < 0){
        exp = exp.trim();
        if(exp.charAt(0) == '(' && exp.charAt(exp.length()-1) == ')')
            return eval(exp.substring(1, exp.length()-1), vars);
        else if(vars.containsKey(exp))
            return vars.get(exp);
        else
            return Double.parseDouble(exp);
    }
    else{
        switch(exp.charAt(operatorIndex)){
            case '+':
                return eval(exp.substring(0, operatorIndex), vars) + eval(exp.substring(operatorIndex+1), vars);
            case '-':
                return eval(exp.substring(0, operatorIndex), vars) - eval(exp.substring(operatorIndex+1), vars);
            case '*':
                return eval(exp.substring(0, operatorIndex), vars) * eval(exp.substring(operatorIndex+1), vars);
            case '/':
                return eval(exp.substring(0, operatorIndex), vars) / eval(exp.substring(operatorIndex+1), vars);
        }
    }
    return 0;
}

}

您需要导入java.util.Map。

以下是我使用此代码的方式:

    ExpressionParser p = new ExpressionParser();
    Map vars = new HashMap<String, Double>();
    vars.put("x", 2.50);
    System.out.println(p.eval(" 5 + 6 * x - 1", vars));

答案 5 :(得分:1)

您可能想要研究的另一个选项是Spring.NET Framework的expression evaluation功能。它也可以比数学做得更多。

但是,如果您不需要其他功能,整个Spring.NET Framework可能会对您的需求有点过分。

答案 6 :(得分:1)

答案 7 :(得分:0)

正如我在此主题(Best Free C# Math Parser using variables, user defined functions, custom operators)中所说,您可以使用Mathos Parser,您可以将其粘贴到源代码中。

        Mathos.Parser.MathParser parser = new Mathos.Parser.MathParser();

        string expr = "(x+(2*x)/(1-x))"; // the expression

        decimal result = 0; // the storage of the result

        parser.LocalVariables.Add("x", 41); // 41 is the value of x

        result = parser.Parse(expr); // parsing

        Console.WriteLine(result); // 38.95

答案 8 :(得分:0)

我建议您使用MEEL

// parse string to IExpression (symbolic type)
IExpression expression = BaseExpression.Parse("(x+(2*x)/(1-x))");

// create your own collection for attributes
var attributes = new MathAttributeCollection();
// create local variable named "x" with value 5
var attributeX = new ScalarAttrInt("x") {Value = new ScalarConstInt(5)};
attributes.Add(attributeX);

// execute math expression where x=5
var result = expression.Execute(attributes);

MessageBox.Show(result.GetText());
// result: 2.5