2010-10-19 22 views
7

¿Hay una forma fácil de analizar una expresión matemática simple representada como una cadena como (x + (2 * x)/(1-x)), proporcionar un valor para x y obtener un resultado?Parse Math Expression

Miré VSAEngine por varios ejemplos en línea, sin embargo, recibo una advertencia de que este ensamblado ha quedado obsoleto y no lo uso.

Si hace alguna diferencia, estoy usando .NET 4.0.

+0

he publicado completa fuente de este problema aquí: http://stackoverflow.com/questions/174664/operators-as-strings –

+0

posible duplicado de [Is es posible compilar y ejecutar un nuevo código en tiempo de ejecución en .NET?] (http://stackoverflow.com/questions/234217/is-it-possible-to-compile-and-execute-new-code-at-runtime- en-red) – nawfal

+0

posible duplicado de [¿Hay un evaluador matemático de cadenas en .NET?] (http://stackoverflow.com/questions/355062/is-there-a-string-math-evaluator-in-net) –

Respuesta

1

Otra opción que quizás desee considerar es la funcionalidad expression evaluation de Spring.NET Framework. También puede hacer mucho más que matemáticas.

Sin embargo, todo el Framework Spring.NET podría ser un poco exagerado para sus necesidades si no necesita el resto de la funcionalidad.

10

Exijo precaución contra la elección de un evaluador de expresiones genérico existente sobre un evaluador de matemáticas especialmente diseñado. La razón de esto es que los evaluadores de expresiones no están limitados solo a las matemáticas. Una persona inteligente podría usar esto para crear una instancia de cualquier tipo en el marco y llamar a cualquier método del tipo, y eso le permitiría hacer algunas cosas decididamente desagradables. Por ejemplo: new System.Net.WebClient().DownloadFile("illegalchildpornurl", "C:\openme.gif") evaluará muy bien en la mayoría de esos casos, y hará exactamente lo que parece (y lo hará delincuente al mismo tiempo).

Esto no significa que no busque algo que ya está escrito. Simplemente significa tener cuidado. Quieres uno que haga matemáticas, y solo matemáticas. La mayor parte de lo que ya está afuera no es tan quisquilloso.

0

Como he respondido en este hilo (Best Free C# Math Parser using variables, user defined functions, custom operators), puede usar Mathos Parser, que puede simplemente pegar en su código fuente.

 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

Desafortunadamente este proyecto está alojado en Codeplex, que se está cerrando. No puedo ni siquiera echar un vistazo a la fuente en Codeplex en este momento. Sería bueno si el proyecto pudiera volver a crearse en Github, Bitbucket o similar. –

+0

@NicFoster, eche un vistazo a https://github.com/MathosProject/Mathos-Parser. También hay otras versiones en https://github.com/MathosProject. – Artem

0

Te recomiendo que uses MEEL para esto.

// 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

poco estuve usando mXparser, que es una biblioteca matemática analizador. Le da mucha flexibilidad, como variables, funciones, constantes, operadores. A continuación, encontrará algunos ejemplos de uso:

Ejemplo 1 - fórmula simple

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

Ejemplo 2 - fórmula con variables, funciones, etc.

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/

Saludos

0

Aquí es una manera de hacerlo. Este código está escrito en Java. Tenga en cuenta que no maneja los números negativos en este momento, pero puede agregar eso.

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; 
} 

}

necesita importar java.util.Map.

Aquí es cómo utilizar este código:

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));