2010-11-12 19 views
12

duplicados posibles:
Is there a string math evaluator in .NET?
Best and shortest way to evaluate mathematical expressions¿Cuál es la mejor forma de ejecutar expresiones matemáticas?

Tengo una variable de cadena

string exp = "12+34+4*56+(23*45+12)2/30" 

¿cuál es la mejor manera de hacerlo? sin el uso de dll de terceros?

+0

"Doing it?" ¿Qué quiere decir con esto? –

+2

@ Livio M. - Supongo que quiere calcular el resultado de la expresión incrustada dentro de la cadena. –

+0

@ Øyvind Bråthen, sí, tienes razón –

Respuesta

17

Necesita un analizador de expresiones matemáticas. La mejor manera en mi opinión es sin reinventar la rueda. Una solución existente de código abierto NCalc es una buena opción.

+2

+1 para concisión, corrección, integridad, incluido un ejemplo. Y realmente me gustaría una solución de código abierto para eso. Excepto si quiere aprender cómo programar cosas así. Luego agregaría una referencia al libro "Compilación de construcción" de Niklaus Wirth. – TheBlastOne

4

Primero, conviértalo en un árbol de expresiones. Si utilizas las clases integradas de Expression obtienes un método de compilación gratis que te da un delegado compilado, que por lo tanto es bastante rápido de evaluar. Esto es útil si desea evaluar su expresión para diferentes parámetros.

2

La manera clásica de Knuth es convertir primero la expresión Infix a una Postfix y luego evaluar la expresión postfija, ver link text. Ambos pasos usan una pila para hacer la mayor parte del procesamiento y son bastante fáciles de hacer.

2

Uso IronPython:

ScriptEngine engine = PythonSingleton.Instance.ScriptEngine; 
ScriptSource source = 
engine.CreateScriptSourceFromString(code, SourceCodeKind.Expression); 

Object res = source.Execute(); 

(Código copiado de this article)

1

Añadir [, ] como operadores en el interior de inicio y final de la cadena a continuación:

números leídos que llenen pila y leer operadores y hacer lo mismo, cuando se enriquece el operador cuyo valor es menor o igual que el operador anterior en la pila POP operador anterior y actúa sobre los números disponibles en la pila de números: *: 3, /: 3,): 4, +: 1, -: 1

[12+34+4*56] ==> 
Round 1: Numbers Stack: 12, Operator stack:[ 
Round 2: Numbers Stack: 12, Operator stack:[, +(1) 
Round 3: Numbers Stack:12,34, Operator stack: [,+(1) 
Round 4: Numbers Stack:12,34, Visited new operator with same or lower value (1) remove previous operator and pop 2 number from number stack and operate on them: So 
Round 4: Numbers Stack:46, Operator stack: [,+(1) 
Round 5: Numbers Stack:46,4 , Operator stack: [,+(1) 
Round 6: Numbers Stack:46,4 , Operator stack: [,+(1),*(2) 
Round 7: Numbers Stack:46,4,56, Operator stack: [,+(1),*(2) 
Round 7: Numbers Stack:46,4,56, Operator stack: [,+(1),*(2) now operator item `]` want to be add, and it's priority is lower than all operators so operators sould be remove from stack and by each operator one number going to be removed: 
Round 7: Numbers Stack:46,224 Operator stack: [,+(1), 
Round 8: Numbers Stack:270 Operator stack: [, 
Round 8: return 270, because ']' intered in Operator stack 
+0

¿No calificaría eso como "reinventar la rueda"? Hay docenas de evaluadores de expresiones numéricas que están bien probados, bien respaldados y más poderosos que eso.¿De qué sirve escribir otro para el código de producción? – Niki

+0

@nikie, en mi humilde opinión OP quiere hacerlo no utilizando un tercero, también escribí esto porque el algoritmo es simple e interesante. –

+0

Acepto que el algoritmo es interesante, y es un buen ejercicio de programación. Pero no está listo para producción (y en mi humilde opinión eso es lo que quiere el OP). Por ejemplo, no veo ninguna disposición para errores de sintaxis buenos (generalmente la parte más difícil al escribir un analizador). – Niki

1

Esto es un poco de un corte, pero yo uso función eval de JavaScript en .NET a través de:

var myEngine = Microsoft.JScript.Vsa.VsaEngine.CreateEngine(); 
string result = Microsoft.JScript.Eval.JScriptEvaluate(expression, myEngine).ToString(); 

Como un bono adicional, puede mezclar funciones matemáticas en su expresión si es necesario

Cuestiones relacionadas