2010-10-19 146 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));