parsingmathexpression式
有没有简单的方法来parsing一个简单的mathexpression式,如(x +(2 * x)/(1-x))这样的string表示,为x提供一个值,并得到一个结果?
我看了几个在线示例VSAEngine,但是,我收到一个警告,说这个程序集已被弃用,不使用它。
如果它有任何区别,我使用.NET 4.0。
你可以尝试使用DataTable.Compute 。
相关的一个是DataColumn.Expression 。
也检查出: 在JavaScript中像在Eval一样在VB.NET中做math
注意:我没有用过这些。
我build议不要select一个现有的通用expression式评估器,而不是专门构build的math评估器。 这是因为expression评估者不仅限于math。 一个聪明的人可以使用这个在框架中创build任何types的实例,并调用任何types的方法,这将允许他做一些决定性的不受欢迎的事情。 例如: new System.Net.WebClient().DownloadFile("illegalchildpornurl", "C:\openme.gif")
将在大多数评估中很好,并做它听起来像(会让你重罪的同时)。
这并不意味着不要寻找已经写好的东西。 这只是要小心。 你想要一个算术,只有math。 大部分已经在那里没有那么挑剔。
我最近使用的是一个mathparsing器库mXparser。 它给了你很大的灵活性,比如variables,函数,常量,操作符。 您将在下面find几个用法示例:
例1 – 简单的公式
Expression e = new Expression("1 + pi"); double v = e.calculate();
示例2 – 包含variables,函数等的公式
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/
最好的祝福
我也会看看Jace( https://github.com/pieterderycke/Jace )。 Jace是一个高性能的mathparsing器和计算引擎,支持所有的.NET风格(.NET 4.x,Windows Phone,Windows Store,…)。 Jace也可以通过NuGet: https : //www.nuget.org/packages/Jace
Spring.NET框架的expression式评估function是您可能想要考虑的另一个选项。 它可以做比math更多的事情。
但是,如果你不需要其余的function,整个Spring.NET框架可能有点矫枉过正。
相关: 具有优先级的公式expression式parsing器 。
正如我在这个线程( 使用variables,用户定义函数,自定义运算符的最佳免费C#mathparsing器)中回答的,您可以使用Mathosparsing器 ,您可以简单地将其粘贴到您的源代码中。
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
我build议你使用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
这是一个办法。 这段代码是用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));