C#如何将一个数学表达式中变量和操作符分析出来? http://blog.csdn.net/cuike519/archive/2004/08/29/87929.aspx抛出异常就是表达式错误 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 在http://www.xue68.com 搜索到过类似的解决方法 目的是为了什么,如果只是要实现算法,可以用以下方法几种方法。http://www.yestar2000.com/TechCenter/1410/TC_16048.htm//===========================================================//四种Eval测试结果:不要用CodeDom做大批量的表达式四则运算//===========================================================--------------------------------------------------------------------------------作者:qiushuiwuhen 来源:未知 加入时间:2004-6-29 浏览次数: -------------------------------------------------------------------------------- 有时候需要表达式运算,如String strExpression="-12 * ( - 2.2 + 7.7 ) - 44 * 2";网上找的,一般是利用CodeDom,见http://www.codeproject.com/csharp/runtime_eval.asp简化为: System.CodeDom.Compiler.ICodeCompiler comp = (new Microsoft.CSharp.CSharpCodeProvider().CreateCompiler()); System.CodeDom.Compiler.CompilerParameters cp = new System.CodeDom.Compiler.CompilerParameters();object qswhEval2(string Expression){ StringBuilder code = new StringBuilder(); code.Append("using System; \n"); code.Append("namespace ADOGuy { \n"); code.Append(" public class _Evaluator { \n"); code.Append(" public object __foo() "); code.Append("{ "); code.AppendFormat(" return ({0}); ", Expression); code.Append("}\n"); code.Append("} }"); System.CodeDom.Compiler.CompilerResults cr = comp.CompileAssemblyFromSource(cp, code.ToString()); System.Reflection.Assembly a = cr.CompiledAssembly; object _Compiled = a.CreateInstance("ADOGuy._Evaluator"); System.Reflection.MethodInfo mi = _Compiled.GetType().GetMethod("__foo"); return mi.Invoke(_Compiled, null);} 但用起来感觉很慢,毕竟需要实时编译。于是,就自己照数据结构书上写了一种算法:string Precede(string p, string q){ switch(p){ case "+": case "-":return ("*/(".IndexOf(q)!=-1)?"<":">"; case "*": case "/":return (q=="(")?"<":">"; case "(":return (q==")")?"=":"<"; case ")":return (q=="(")?"?":">"; case "#":return (q=="#")?"=":"<"; } return "?";}Double Operate(Double a,char o,Double b){ switch(o) { case '+':return a+b; case '-':return a-b; case '*':return a*b; case '/':return a/b; } return 0;}Object qswhEval1(string Expression){ /*************(qiushuiwuhen 2002-12-14)****************/ Stack nArr=new Stack(),oArr=new Stack(); int j=0; Double a=0,b=0; string w=""; char o; MatchCollection arr=Regex.Matches(Expression.Replace(" ","")+"#",@"(((?<=(^|\())-)?\d+(\.\d+)?|\D)"); oArr.Push('#'); w=Convert.ToString(arr[j++]); while(!(w=="#"&&Convert.ToString(oArr.Peek())=="#")){ if("+-*/()#".IndexOf(w)!=-1){ switch(Precede(oArr.Peek().ToString(),w)){ case "<": oArr.Push(w); w=Convert.ToString(arr[j++]); break; case "=": oArr.Pop(); w=Convert.ToString(arr[j++]); break; case ">": o=Convert.ToChar(oArr.Pop()); b=Convert.ToDouble(nArr.Pop()); a=Convert.ToDouble(nArr.Pop()); nArr.Push(Operate(a,o,b)); break; default: return "Error"; break; } }else{ nArr.Push(w); w=Convert.ToString(arr[j++]); } } return nArr.Pop();}还有利用JScript的Eval的两种算法Microsoft.JScript.Vsa.VsaEngine ve=Microsoft.JScript.Vsa.VsaEngine.CreateEngine();object qswhEval3(string Expression){ return Microsoft.JScript.Eval.JScriptEvaluate(Expression,ve);}object qswhEval4(string Expression){ return qswhJs.qswhEval.Eval(Expression);}第四种需先建立一js编译为dll,如下代码import System;package qswhJs { class qswhEval { static function Eval(Expression):Object { return eval(Expression); } }}测试代码如下:void Page_Load(Object o,EventArgs ea){ String strExpression="-12 * ( - 2.2 + 7.7 ) - 44 * 2"; int i=0,c=100; DateTime d1,d2;cp.GenerateExecutable = false;cp.GenerateInMemory = true; d1=DateTime.Now; for(i=0;i<c;i++)qswhEval1(strExpression); d2=DateTime.Now; Response.Write("方法一:对表达式分析 "+d2.Subtract(d1)+"<br>"); d1=DateTime.Now; for(i=0;i<c;i++)qswhEval2(strExpression); d2=DateTime.Now; Response.Write("方法二:利用CodeCom "+d2.Subtract(d1)+"<br>"); d1=DateTime.Now; for(i=0;i<c;i++)qswhEval3(strExpression); d2=DateTime.Now; Response.Write("方法三:利用Jscript+Vsa "+d2.Subtract(d1)+"<br>"); d1=DateTime.Now; for(i=0;i<c;i++)qswhEval4(strExpression); d2=DateTime.Now; Response.Write("方法四:利用Jsc+Dll "+d2.Subtract(d1)+"<br>");}测试结果:方法一:对表达式分析 00:00:00.1702448方法二:利用CodeCom 00:00:23.7942144方法三:利用Jscript+Vsa 00:00:00.1902736方法四:利用Jsc+Dll 00:00:00.2403456在此推荐第一种(如果要纯CSharp的话)和第三种(代码简单,功能更多) 如果是 sin(a)+b 怎么伴,我里面还要对数学函数解析 C# 返回json数据 重新加载winform。自编号改变 C# P/Invoke 调用C++函数问题 C#如何使用Lable控件输出数组 ~~~~急求,打包文件的问题,真的救命的了~~~~~ C#文件重命名的方法 怎么调用<object id="mm" data="t.htm" ...></object>中t.htm的javascript方法 怎样获得datagrid中某行某列的内容? 心情不高兴~~~~~~~散分 熟悉NET命名空间system.management的进!有疑问 简单的多线程问题! 关于控件间消息的传递问题
http://www.yestar2000.com/TechCenter/1410/TC_16048.htm
//===========================================================
//四种Eval测试结果:不要用CodeDom做大批量的表达式四则运算
//===========================================================--------------------------------------------------------------------------------
作者:qiushuiwuhen 来源:未知 加入时间:2004-6-29 浏览次数:
--------------------------------------------------------------------------------
有时候需要表达式运算,如
String strExpression="-12 * ( - 2.2 + 7.7 ) - 44 * 2";网上找的,一般是利用CodeDom,见
http://www.codeproject.com/csharp/runtime_eval.asp简化为:
System.CodeDom.Compiler.ICodeCompiler comp = (new Microsoft.CSharp.CSharpCodeProvider().CreateCompiler());
System.CodeDom.Compiler.CompilerParameters cp = new System.CodeDom.Compiler.CompilerParameters();object qswhEval2(string Expression){
StringBuilder code = new StringBuilder();
code.Append("using System; \n");
code.Append("namespace ADOGuy { \n");
code.Append(" public class _Evaluator { \n");
code.Append(" public object __foo() ");
code.Append("{ ");
code.AppendFormat(" return ({0}); ", Expression);
code.Append("}\n");
code.Append("} }");
System.CodeDom.Compiler.CompilerResults cr = comp.CompileAssemblyFromSource(cp, code.ToString());
System.Reflection.Assembly a = cr.CompiledAssembly;
object _Compiled = a.CreateInstance("ADOGuy._Evaluator");
System.Reflection.MethodInfo mi = _Compiled.GetType().GetMethod("__foo");
return mi.Invoke(_Compiled, null);
}
但用起来感觉很慢,毕竟需要实时编译。于是,就自己照数据结构书上写了一种算法:
string Precede(string p, string q){
switch(p){
case "+":
case "-":return ("*/(".IndexOf(q)!=-1)?"<":">";
case "*":
case "/":return (q=="(")?"<":">";
case "(":return (q==")")?"=":"<";
case ")":return (q=="(")?"?":">";
case "#":return (q=="#")?"=":"<";
}
return "?";
}
Double Operate(Double a,char o,Double b)
{
switch(o)
{
case '+':return a+b;
case '-':return a-b;
case '*':return a*b;
case '/':return a/b;
}
return 0;
}Object qswhEval1(string Expression){
/*************(qiushuiwuhen 2002-12-14)****************/
Stack nArr=new Stack(),oArr=new Stack();
int j=0;
Double a=0,b=0;
string w="";
char o;
MatchCollection arr=Regex.Matches(Expression.Replace(" ","")+"#",@"(((?<=(^|\())-)?\d+(\.\d+)?|\D)");
oArr.Push('#');
w=Convert.ToString(arr[j++]);
while(!(w=="#"&&Convert.ToString(oArr.Peek())=="#")){
if("+-*/()#".IndexOf(w)!=-1){
switch(Precede(oArr.Peek().ToString(),w)){
case "<":
oArr.Push(w);
w=Convert.ToString(arr[j++]);
break;
case "=":
oArr.Pop();
w=Convert.ToString(arr[j++]);
break;
case ">":
o=Convert.ToChar(oArr.Pop());
b=Convert.ToDouble(nArr.Pop());
a=Convert.ToDouble(nArr.Pop());
nArr.Push(Operate(a,o,b));
break;
default:
return "Error";
break;
}
}else{
nArr.Push(w);
w=Convert.ToString(arr[j++]);
}
}
return nArr.Pop();
}还有利用JScript的Eval的两种算法
Microsoft.JScript.Vsa.VsaEngine ve=Microsoft.JScript.Vsa.VsaEngine.CreateEngine();
object qswhEval3(string Expression){
return Microsoft.JScript.Eval.JScriptEvaluate(Expression,ve);
}object qswhEval4(string Expression){
return qswhJs.qswhEval.Eval(Expression);
}第四种需先建立一js编译为dll,如下代码
import System;package qswhJs {
class qswhEval {
static function Eval(Expression):Object { return eval(Expression); }
}
}测试代码如下:
void Page_Load(Object o,EventArgs ea){
String strExpression="-12 * ( - 2.2 + 7.7 ) - 44 * 2";
int i=0,c=100;
DateTime d1,d2;
cp.GenerateExecutable = false;
cp.GenerateInMemory = true;
d1=DateTime.Now;
for(i=0;i<c;i++)qswhEval1(strExpression);
d2=DateTime.Now;
Response.Write("方法一:对表达式分析 "+d2.Subtract(d1)+"<br>");
d1=DateTime.Now;
for(i=0;i<c;i++)qswhEval2(strExpression);
d2=DateTime.Now;
Response.Write("方法二:利用CodeCom "+d2.Subtract(d1)+"<br>");
d1=DateTime.Now;
for(i=0;i<c;i++)qswhEval3(strExpression);
d2=DateTime.Now;
Response.Write("方法三:利用Jscript+Vsa "+d2.Subtract(d1)+"<br>");
d1=DateTime.Now;
for(i=0;i<c;i++)qswhEval4(strExpression);
d2=DateTime.Now;
Response.Write("方法四:利用Jsc+Dll "+d2.Subtract(d1)+"<br>");
}测试结果:方法一:对表达式分析 00:00:00.1702448
方法二:利用CodeCom 00:00:23.7942144
方法三:利用Jscript+Vsa 00:00:00.1902736
方法四:利用Jsc+Dll 00:00:00.2403456在此推荐第一种(如果要纯CSharp的话)
和第三种(代码简单,功能更多)