2010-10-19 123 views
7

有没有简单的方法来解析表示为一个字符串,如(x +(2 * x)/(1-x))的简单的数学表达式,为x提供一个值,并得到一个结果?解析数学表达式

我查看了几个在线示例中的VSAEngine,但是,我收到了警告,表示此程序集已被弃用,不会使用它。

如果它有什么不同,我使用.NET 4.0。

+0

我张贴了这个问题完整的源代码在这里:http://stackoverflow.com/questions/174664/operators-as-strings的[是 – 2010-10-19 22:08:28

+0

可能重复有可能在.NET中运行时编译和执行新代码?](http://stackoverflow.com/questions/234217/is-it-possible-to-compile-and-execute-new-code-at-runtime-在网) – nawfal 2013-05-31 16:23:06

+0

可能的重复[有没有在.NET中的字符串数学评估?](http://stackoverflow.com/questions/355062/is-there-a-string-math-evaluator-in-net) – 2014-10-15 13:13:30

回答

1

您可能想要考虑的另一个选项是Spring.NET框架的expression evaluation功能。它也可以做比数学更多的事情。

但是,如果您不需要其余的功能,整个Spring.NET框架可能会有点矫枉过正以满足您的需求。

10

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

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

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 
+0

不幸的是,这个项目是在Codeplex上进行的,该项目正在关闭。我无法设法在Codeplex上查看源代码。如果该项目可以在Github或Bitbucket等上重新托管,那将会很好。 – 2017-06-12 05:07:19

+0

@NicFoster,请看看https://github.com/MathosProject/Mathos-Parser。 https://github.com/MathosProject上还有其他版本。 – Artem 2017-06-12 07:39:19

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 
5

我最近使用的是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/

问候

0

下面是做到这一点的方法之一。这段代码是用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));