class Evaluator { /// <summary> /// 梬源宒 /// </summary> /// <param name="Expression"></param> /// <returns></returns> public static object Eval(string Expression) { Expression e = new Expression(Expression); return e.Result; } /// <summary> /// 雄怓晤祒腔源宒, 厒僅怮鞣 /// </summary> /// <param name="expression"></param> /// <returns></returns> public static object Eval1(string expression) { CodeDomProvider comp = new CSharpCodeProvider(); CompilerParameters cp = new CompilerParameters(); MethodInfo mi; StringBuilder codeBuilder = new StringBuilder(); codeBuilder.AppendLine("using System;"); codeBuilder.AppendLine("using Microsoft.CSharp;"); codeBuilder.AppendLine("public class Mode"); codeBuilder.AppendLine("{"); codeBuilder.AppendLine(" public static object Func()"); codeBuilder.AppendLine(" {"); codeBuilder.AppendLine(" try"); codeBuilder.AppendLine(" {"); codeBuilder.AppendLine(" return " + (Functions.StrIsEmpty(expression) ? "0" : expression) + ";"); codeBuilder.AppendLine(" }"); codeBuilder.AppendLine(" catch"); codeBuilder.AppendLine(" {"); codeBuilder.AppendLine(" return \"\";"); codeBuilder.AppendLine(" }"); codeBuilder.AppendLine(" }"); codeBuilder.AppendLine("}"); cp.ReferencedAssemblies.Add("System.dll"); cp.GenerateExecutable = false; cp.GenerateInMemory = true; string code = codeBuilder.ToString(); CompilerResults cr = comp.CompileAssemblyFromSource(cp, code); if (cr.Errors.HasErrors) { return null; } else { Assembly a = cr.CompiledAssembly; Type t = a.GetType("Mode"); //object mode = a.CreateInstance("Mode"); mi = t.GetMethod("Func", BindingFlags.Static | BindingFlags.Public); return mi.Invoke(null, new object[0]); } } class Expression { IList<string> InputLists = new List<string>(); static IList<string> OperatorList; static Expression() { OperatorList = new List<string>(); OperatorList.Add("+"); OperatorList.Add("-"); OperatorList.Add("*"); OperatorList.Add("/"); OperatorList.Add("("); OperatorList.Add(")"); OperatorList.Add("#"); } public Expression(string Input) { InputLists = new List<string>(); Input = Input.Replace(" ", ""); string OPNum = ""; while (Input.Length > 0) { OPNum = ""; while (Char.IsNumber(Input[0]) || Input[0] == '.' || Input[0] == '-') { if (Input[0] == '.' && OPNum == "") break; //判断是负号/减号 if (Input[0] == '-') { if (OPNum != "") break; if (InputLists.Count > 0) { string Prior = InputLists[InputLists.Count - 1]; if(Prior != "+" && Prior != "-" && Prior != "*" && Prior != "/") break; } } OPNum += Input[0].ToString(); Input = Input.Substring(1); if (Input == "") break; } if (OPNum != "") InputLists.Add(OPNum); if (Input.Length > 0) { InputLists.Add(Input[0].ToString()); Input = Input.Substring(1); } } InputLists.Add("#"); }
Stack<string> OPStack; Stack<string> NumStack; /// <summary> /// 桶湛宒賦彆 /// </summary> public double Result { get { OPStack = new Stack<string>(); NumStack = new Stack<string>(); Position = 0; OPStack.Push("#"); string Word = ReadNext(); while (Word != "#" || OPStack.Peek() != "#") { if (!isOperator(Word)) { NumStack.Push(Word); Word = ReadNext(); continue; } else { switch (Priority(Word)) { case "<": OPStack.Push(Word); Word = ReadNext(); break; case "=": OPStack.Pop(); Word = ReadNext(); break; case ">": string OP = OPStack.Pop(); double b = Functions.StrToDouble(NumStack.Pop()); double a = Functions.StrToDouble(NumStack.Pop()); NumStack.Push(Operate(a, OP, b)); break; } } if (Word == "") break; } return Functions.StrToDouble(NumStack.Pop()); } } string Operate(double a, string OP, double b) { double Result = 0; switch (OP) { case "+": Result = a + b; break; case "-": Result = a - b; break; case "*": Result = a * b; break; case "/": Result = a / b; break; } return Result.ToString(); } int Position = 0; string ReadNext() { if (InputLists.Count > Position) { return InputLists[Position++]; } return ""; } bool isOperator(string OP) { return OperatorList.Contains(OP); } string Priority(string OP) { string TopOP = OPStack.Peek(); switch (TopOP) { case "+": case "-": if (OP == "*" || OP == "/" || OP == "(") return "<"; return ">"; case "*": case "/": if (OP == "(") return "<"; return ">"; case "(": if (OP == ")") return "="; if (OP == "#") throw new BusinessLogicException("OP_ERROR"); return "<"; case ")": return ">"; case "#": if (OP == "#") return "="; return "<"; } return ""; } } } 需要 using System.CodeDom.Compiler; using System.Reflection; using Microsoft.CSharp;
function 计算(a as string) as integer if 有括号 then replace(括号里的东西,计算(括号里的东西).tostring) else if 有乘号 or 有除号 replace('X*X',(X*X).tostring) '如果第一个是除号就先做除法 else 只有加减法的我就不用说了吧?注意这里是递归出口就行 end if end if end function
program exsj_1; const max=100; var number:array[0..max] of integer; symbol:array[1..max] of char; s,t:string; i,p,j,code:integer; procedure push;{算符入栈运算} begin inc(p);symbol[p]:=s[i]; end;procedure pop;{运算符栈顶元素出栈,并取出操作数栈元素完成相应的运算} begin dec(p); case symbol[p+1] of '+':inc(number[p],number[p+1]); '-':dec(number[p],number[p+1]); '*':number[p]:=number[p]*number[p+1]; '/':number[p]:=number[p] div number[p+1]; end; end;function can:boolean;{判断运算符的优先级别,建立标志函数} begin can:=true; if (s[i] in ['+','-']) and (symbol[p]<>'(') then exit; if (s[i] in ['*','/']) and (symbol[p] in ['*','/']) then exit; can:=false; end;begin write('String : '); readln(s); s:='('+s+')'; i:=1; p:=0; while i<=length(s) do begin while s[i]='(' do {左括号处理] begin push; inc(i); end; j:=i; repeat {取数入操作数栈} inc(i); until (s[i]<'0') or (s[i]>'9'); t:=copy(s,j,i-j); val(t,number[p],code); repeat if s[i]=')' then {右括号处理} begin while symbol[p]<>'(' do pop; dec(p); number[p]:=number[p+1]; end else begin {根据标志函数值作运算符入栈或出栈运算处理} while can do pop; push; end; inc(i); until (i>length(s)) or (s[i-1]<>')'); end; write('Result=',number[0]); readln; end.上面的是用栈的标准算法,我喜欢递归
{
/// <summary>
/// 梬源宒
/// </summary>
/// <param name="Expression"></param>
/// <returns></returns>
public static object Eval(string Expression)
{
Expression e = new Expression(Expression);
return e.Result;
} /// <summary>
/// 雄怓晤祒腔源宒, 厒僅怮鞣
/// </summary>
/// <param name="expression"></param>
/// <returns></returns>
public static object Eval1(string expression)
{
CodeDomProvider comp = new CSharpCodeProvider();
CompilerParameters cp = new CompilerParameters();
MethodInfo mi;
StringBuilder codeBuilder = new StringBuilder(); codeBuilder.AppendLine("using System;");
codeBuilder.AppendLine("using Microsoft.CSharp;");
codeBuilder.AppendLine("public class Mode");
codeBuilder.AppendLine("{");
codeBuilder.AppendLine(" public static object Func()");
codeBuilder.AppendLine(" {");
codeBuilder.AppendLine(" try");
codeBuilder.AppendLine(" {");
codeBuilder.AppendLine(" return " + (Functions.StrIsEmpty(expression) ? "0" : expression) + ";");
codeBuilder.AppendLine(" }");
codeBuilder.AppendLine(" catch");
codeBuilder.AppendLine(" {");
codeBuilder.AppendLine(" return \"\";");
codeBuilder.AppendLine(" }");
codeBuilder.AppendLine(" }");
codeBuilder.AppendLine("}"); cp.ReferencedAssemblies.Add("System.dll");
cp.GenerateExecutable = false;
cp.GenerateInMemory = true; string code = codeBuilder.ToString();
CompilerResults cr = comp.CompileAssemblyFromSource(cp, code); if (cr.Errors.HasErrors)
{
return null;
}
else
{
Assembly a = cr.CompiledAssembly;
Type t = a.GetType("Mode");
//object mode = a.CreateInstance("Mode");
mi = t.GetMethod("Func", BindingFlags.Static | BindingFlags.Public);
return mi.Invoke(null, new object[0]);
}
} class Expression
{
IList<string> InputLists = new List<string>();
static IList<string> OperatorList;
static Expression()
{
OperatorList = new List<string>();
OperatorList.Add("+");
OperatorList.Add("-");
OperatorList.Add("*");
OperatorList.Add("/");
OperatorList.Add("(");
OperatorList.Add(")");
OperatorList.Add("#");
}
public Expression(string Input)
{
InputLists = new List<string>();
Input = Input.Replace(" ", "");
string OPNum = "";
while (Input.Length > 0)
{
OPNum = "";
while (Char.IsNumber(Input[0]) || Input[0] == '.' || Input[0] == '-')
{
if (Input[0] == '.' && OPNum == "")
break;
//判断是负号/减号
if (Input[0] == '-')
{
if (OPNum != "")
break;
if (InputLists.Count > 0)
{
string Prior = InputLists[InputLists.Count - 1];
if(Prior != "+" && Prior != "-" && Prior != "*" && Prior != "/")
break;
}
}
OPNum += Input[0].ToString();
Input = Input.Substring(1);
if (Input == "") break;
}
if (OPNum != "")
InputLists.Add(OPNum);
if (Input.Length > 0)
{
InputLists.Add(Input[0].ToString());
Input = Input.Substring(1);
}
}
InputLists.Add("#");
}
Stack<string> NumStack;
/// <summary>
/// 桶湛宒賦彆
/// </summary>
public double Result
{
get
{
OPStack = new Stack<string>();
NumStack = new Stack<string>();
Position = 0; OPStack.Push("#");
string Word = ReadNext();
while (Word != "#" || OPStack.Peek() != "#")
{
if (!isOperator(Word))
{
NumStack.Push(Word);
Word = ReadNext();
continue;
}
else
{
switch (Priority(Word))
{
case "<":
OPStack.Push(Word);
Word = ReadNext();
break;
case "=":
OPStack.Pop();
Word = ReadNext();
break;
case ">":
string OP = OPStack.Pop();
double b = Functions.StrToDouble(NumStack.Pop());
double a = Functions.StrToDouble(NumStack.Pop());
NumStack.Push(Operate(a, OP, b));
break;
}
} if (Word == "")
break;
}
return Functions.StrToDouble(NumStack.Pop());
}
}
string Operate(double a, string OP, double b)
{
double Result = 0;
switch (OP)
{
case "+":
Result = a + b;
break;
case "-":
Result = a - b;
break;
case "*":
Result = a * b;
break;
case "/":
Result = a / b;
break;
}
return Result.ToString();
}
int Position = 0;
string ReadNext()
{
if (InputLists.Count > Position)
{
return InputLists[Position++];
}
return "";
}
bool isOperator(string OP)
{
return OperatorList.Contains(OP);
}
string Priority(string OP)
{
string TopOP = OPStack.Peek();
switch (TopOP)
{
case "+":
case "-":
if (OP == "*" || OP == "/" || OP == "(")
return "<";
return ">";
case "*":
case "/":
if (OP == "(")
return "<";
return ">";
case "(":
if (OP == ")")
return "=";
if (OP == "#")
throw new BusinessLogicException("OP_ERROR");
return "<";
case ")":
return ">";
case "#":
if (OP == "#")
return "=";
return "<";
}
return "";
}
}
}
需要
using System.CodeDom.Compiler;
using System.Reflection;
using Microsoft.CSharp;
if 有括号 then
replace(括号里的东西,计算(括号里的东西).tostring)
else
if 有乘号 or 有除号
replace('X*X',(X*X).tostring) '如果第一个是除号就先做除法
else
只有加减法的我就不用说了吧?注意这里是递归出口就行
end if
end if
end function
const
max=100;
var
number:array[0..max] of integer;
symbol:array[1..max] of char;
s,t:string;
i,p,j,code:integer;
procedure push;{算符入栈运算}
begin
inc(p);symbol[p]:=s[i];
end;procedure pop;{运算符栈顶元素出栈,并取出操作数栈元素完成相应的运算}
begin
dec(p);
case symbol[p+1] of
'+':inc(number[p],number[p+1]);
'-':dec(number[p],number[p+1]);
'*':number[p]:=number[p]*number[p+1];
'/':number[p]:=number[p] div number[p+1];
end;
end;function can:boolean;{判断运算符的优先级别,建立标志函数}
begin
can:=true;
if (s[i] in ['+','-']) and (symbol[p]<>'(') then exit;
if (s[i] in ['*','/']) and (symbol[p] in ['*','/']) then exit;
can:=false;
end;begin
write('String : '); readln(s); s:='('+s+')'; i:=1; p:=0;
while i<=length(s) do
begin
while s[i]='(' do {左括号处理]
begin
push; inc(i);
end;
j:=i;
repeat {取数入操作数栈}
inc(i);
until (s[i]<'0') or (s[i]>'9');
t:=copy(s,j,i-j); val(t,number[p],code);
repeat
if s[i]=')' then {右括号处理}
begin
while symbol[p]<>'(' do pop;
dec(p); number[p]:=number[p+1];
end
else
begin {根据标志函数值作运算符入栈或出栈运算处理}
while can do pop;
push;
end;
inc(i);
until (i>length(s)) or (s[i-1]<>')');
end;
write('Result=',number[0]);
readln;
end.上面的是用栈的标准算法,我喜欢递归