执行数学表达式的最佳方法是什么?

时间:2010-11-12 09:04:47

标签: c#

  

可能重复:
  Is there a string math evaluator in .NET?
  Best and shortest way to evaluate mathematical expressions

我有一个字符串变量

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

最好的方法是什么?没有使用第三方dll?

6 个答案:

答案 0 :(得分:17)

您需要一个数学表达式解析器。在我看来,最好的方法是不重新发明轮子。现有的开源解决方案NCalc是一个不错的选择。

答案 1 :(得分:4)

首先将其翻译为表达式树。如果你使用内置的Expression类,你会得到一个免费的编译方法,它给你一个编译的委托,因此评估起来非常快。如果要评估不同参数的表达式,这非常有用。

答案 2 :(得分:2)

Knuth的经典方法是首先将Infix表达式转换为Postfix表达式然后评估后缀表达式,请参阅link text。这两个步骤都使用Stack来完成大部分处理,并且相当容易。

答案 3 :(得分:2)

使用IronPython:

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

Object res = source.Execute();

(从this article复制的代码)

答案 4 :(得分:1)

在字符串的开头和结尾添加[]作为运算符:

读取数字将它们填入堆栈并读取运算符并执行相同操作,当您丰富运算符时,其值低于或等于堆栈POP上一个运算符中的前一个运算符,并对数字堆栈中的可用数字执行操作: *: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

答案 5 :(得分:1)

这有点像黑客,但我在.net中使用javascript的eval函数:

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

作为额外的奖励,如果需要,你可以将数学函数混合到你的表达中