下面是文件的内容,将其全部复制到c#语言下的一个类中即可按上文要求的使用。 ///<author>Emad Barsoum</author>///<email>ebarsoum@msn.com</email>///<date>March 23, 2002</date>///<copyright>///This code is Copyright to Emad Barsoum, it can be used or changed for free without removing the header///information which is the author name, email and date or refer to this information if any change made. ///</copyright>///<summary>///This class <c>Function</c> use the transformation from infix notation to postfix notation to evalute most///Mathematic expression, it support most operators (+,-,*,/,%,^), functions from 0 to any number of parameters///and also a user defined function by using delegate, also it support variables in the expression, it will///generate a symbol table that can be updated at run time.///</summary> using System;using System.Collections; namespace EB.Math{ /// <summary> /// </summary> /// public enum Type{Variable,Value,UnaryOperator,Operator,Function,Result,Bracket,Comma,Error} public struct Symbol { public string m_name; public double m_value; public Type m_type; public override string ToString() { return m_name; } } public delegate Symbol EvaluateFunctionDelegate(string name, params Object[] args); public class Function { public double Result { get { return m_result; } } public ArrayList Equation { get { return (ArrayList)m_equation.Clone(); } } public ArrayList Postfix { get { return (ArrayList)m_postfix.Clone(); } } public EvaluateFunctionDelegate DefaultFunctionEvaluation { set { m_defaultFunctionEvaluation = value; } } public bool Error { get { return m_bError; } } public string ErrorDescription { get { return m_sErrorDescription; } } public ArrayList Variables { get { ArrayList var = new ArrayList(); foreach(Symbol sym in m_equation) { if((sym.m_type == Type.Variable) && (!var.Contains(sym))) var.Add(sym); } return var; } set { foreach(Symbol sym in value) { for(int i=0;i<m_postfix.Count;i++) { if((sym.m_name == ((Symbol)m_postfix[i]).m_name) && (((Symbol)m_postfix[i]).m_type == Type.Variable)) { Symbol sym1 = (Symbol)m_postfix[i]; sym1.m_value = sym.m_value; m_postfix[i] = sym1; } } } } } public Function() {} public void Parse(string equation) { int state = 1; string temp = ""; Symbol ctSymbol; m_bError = false; m_sErrorDescription = "None"; m_equation.Clear(); m_postfix.Clear(); int nPos = 0; //-- Remove all white spaces from the equation string -- equation = equation.Trim(); while((nPos=equation.IndexOf(' ')) != -1) equation = equation.Remove(nPos,1); for(int i=0;i<equation.Length;i++) { switch(state) { case 1: if(Char.IsNumber(equation[i])) { state = 2; temp += equation[i]; } else if(Char.IsLetter(equation[i])) { state = 3; temp += equation[i]; } else { ctSymbol.m_name = equation[i].ToString(); ctSymbol.m_value = 0; switch(ctSymbol.m_name) { case ",": ctSymbol.m_type = Type.Comma; break; case "(": case ")": case "[": case "]": case "{": case "}": ctSymbol.m_type = Type.Bracket; break; default: if(m_equation.Count == 0) ctSymbol.m_type = Type.UnaryOperator; else if((((Symbol)m_equation[m_equation.Count-1]).m_type == Type.Value) || (((Symbol)m_equation[m_equation.Count-1]).m_type == Type.Variable) || (((Symbol)m_equation[m_equation.Count-1]).m_name == ")") || (((Symbol)m_equation[m_equation.Count-1]).m_name == "]") || (((Symbol)m_equation[m_equation.Count-1]).m_name == "}")) ctSymbol.m_type = Type.Operator; else ctSymbol.m_type = Type.UnaryOperator; break; } m_equation.Add(ctSymbol); } break; case 2: if((Char.IsNumber(equation[i])) || (equation[i] == '.')) temp += equation[i]; else if(!Char.IsLetter(equation[i])) { state = 1; ctSymbol.m_name = temp; ctSymbol.m_value = Double.Parse(temp); ctSymbol.m_type = Type.Value; m_equation.Add(ctSymbol); ctSymbol.m_name = equation[i].ToString(); ctSymbol.m_value = 0; switch(ctSymbol.m_name) { case ",": ctSymbol.m_type = Type.Comma; break; case "(": case ")": case "[": case "]": case "{": case "}": ctSymbol.m_type = Type.Bracket; break; default: if(m_equation.Count == 0) ctSymbol.m_type = Type.UnaryOperator; else if((((Symbol)m_equation[m_equation.Count-1]).m_type == Type.Value) || (((Symbol)m_equation[m_equation.Count-1]).m_type == Type.Variable) || (((Symbol)m_equation[m_equation.Count-1]).m_name == ")") || (((Symbol)m_equation[m_equation.Count-1]).m_name == "]") || (((Symbol)m_equation[m_equation.Count-1]).m_name == "}")) ctSymbol.m_type = Type.Operator; else ctSymbol.m_type = Type.UnaryOperator; break; } m_equation.Add(ctSymbol); temp = ""; } break; case 3: if(Char.IsLetterOrDigit(equation[i])) temp += equation[i]; else { state = 1; ctSymbol.m_name = temp; ctSymbol.m_value = 0; if(equation[i] == '(') ctSymbol.m_type = Type.Function; else { if(ctSymbol.m_name == "pi") ctSymbol.m_value = System.Math.PI; else if(ctSymbol.m_name == "e") ctSymbol.m_value = System.Math.E; ctSymbol.m_type = Type.Variable; } m_equation.Add(ctSymbol); ctSymbol.m_name = equation[i].ToString(); ctSymbol.m_value = 0; switch(ctSymbol.m_name) { case ",": ctSymbol.m_type = Type.Comma; break; case "(": case ")": case "[": case "]": case "{": case "}": ctSymbol.m_type = Type.Bracket; break; default: if(m_equation.Count == 0) ctSymbol.m_type = Type.UnaryOperator; else if((((Symbol)m_equation[m_equation.Count-1]).m_type == Type.Value) || (((Symbol)m_equation[m_equation.Count-1]).m_type == Type.Variable) || (((Symbol)m_equation[m_equation.Count-1]).m_name == ")") || (((Symbol)m_equation[m_equation.Count-1]).m_name == "]") || (((Symbol)m_equation[m_equation.Count-1]).m_name == "}")) ctSymbol.m_type = Type.Operator; else ctSymbol.m_type = Type.UnaryOperator; break; } m_equation.Add(ctSymbol); temp = ""; } break; } } if(temp != "") { ctSymbol.m_name = temp; if(state == 2) { ctSymbol.m_value = Double.Parse(temp); ctSymbol.m_type = Type.Value; } else { if(ctSymbol.m_name == "pi") ctSymbol.m_value = System.Math.PI; else if(ctSymbol.m_name == "e") ctSymbol.m_value = System.Math.E; else ctSymbol.m_value = 0; ctSymbol.m_type = Type.Variable; } m_equation.Add(ctSymbol); } } public void Infix2Postfix() { Symbol tpSym; Stack tpStack = new Stack(); foreach(Symbol sym in m_equation) { if((sym.m_type == Type.Value) || (sym.m_type == Type.Variable)) m_postfix.Add(sym); else if((sym.m_name == "(") || (sym.m_name == "[") || (sym.m_name == "{")) tpStack.Push(sym); else if((sym.m_name == ")") || (sym.m_name == "]") || (sym.m_name == "}")) { if(tpStack.Count > 0) { tpSym = (Symbol)tpStack.Pop(); while((tpSym.m_name != "(") && (tpSym.m_name != "[") && (tpSym.m_name != "{")) { m_postfix.Add(tpSym); tpSym = (Symbol)tpStack.Pop(); } } } else if(sym.m_type == Type.UnaryOperator) { tpStack.Push(sym); } else { if(tpStack.Count > 0) { tpSym = (Symbol)tpStack.Pop(); while((tpStack.Count != 0) && ((tpSym.m_type == Type.UnaryOperator) || (tpSym.m_type == Type.Operator) || (tpSym.m_type == Type.Function) || (tpSym.m_type == Type.Comma)) && (Precedence(tpSym) >= Precedence(sym))) { m_postfix.Add(tpSym); tpSym = (Symbol)tpStack.Pop(); } if(((tpSym.m_type == Type.UnaryOperator) || (tpSym.m_type == Type.Operator) || (tpSym.m_type == Type.Function) || (tpSym.m_type == Type.Comma)) && (Precedence(tpSym) >= Precedence(sym))) m_postfix.Add(tpSym); else tpStack.Push(tpSym); } tpStack.Push(sym); } } while(tpStack.Count > 0) { tpSym = (Symbol)tpStack.Pop(); m_postfix.Add(tpSym); } } public void EvaluatePostfix() { Symbol tpSym1, tpSym2, tpResult; Stack tpStack = new Stack(); ArrayList fnParam = new ArrayList(); m_bError = false; foreach(Symbol sym in m_postfix) { if((sym.m_type == Type.Value) || (sym.m_type == Type.Variable) || (sym.m_type == Type.Result)) tpStack.Push(sym); else if(sym.m_type == Type.UnaryOperator) { tpSym1 = (Symbol)tpStack.Pop(); tpResult = Evaluate(sym, tpSym1); if(tpResult.m_type == Type.Error) { m_bError = true; m_sErrorDescription = tpResult.m_name; return; } tpStack.Push(tpResult); } else if(sym.m_type == Type.Operator) { tpSym1 = (Symbol)tpStack.Pop(); tpSym2 = (Symbol)tpStack.Pop(); tpResult = Evaluate(tpSym2, sym, tpSym1); if(tpResult.m_type == Type.Error) { m_bError = true; m_sErrorDescription = tpResult.m_name; return; } tpStack.Push(tpResult); } else if(sym.m_type == Type.Comma) { tpStack.Push(sym); } else if(sym.m_type == Type.Function) { fnParam.Clear(); tpSym1 = (Symbol)tpStack.Pop(); if((tpSym1.m_type == Type.Value) || (tpSym1.m_type == Type.Variable) || (tpSym1.m_type == Type.Result)) { tpResult = EvaluateFunction(sym.m_name,tpSym1); if(tpResult.m_type == Type.Error) { m_bError = true; m_sErrorDescription = tpResult.m_name; return; } tpStack.Push(tpResult); } else if(tpSym1.m_type == Type.Comma) { while(tpSym1.m_type == Type.Comma) { tpSym1 = (Symbol)tpStack.Pop(); fnParam.Add(tpSym1); tpSym1 = (Symbol)tpStack.Pop(); } fnParam.Add(tpSym1); tpResult = EvaluateFunction(sym.m_name,fnParam.ToArray()); if(tpResult.m_type == Type.Error) { m_bError = true; m_sErrorDescription = tpResult.m_name; return; } tpStack.Push(tpResult); } else { tpStack.Push(tpSym1); tpResult = EvaluateFunction(sym.m_name); if(tpResult.m_type == Type.Error) { m_bError = true; m_sErrorDescription = tpResult.m_name; return; } tpStack.Push(tpResult); } } } if(tpStack.Count == 1) { tpResult = (Symbol)tpStack.Pop(); m_result = tpResult.m_value; } } protected int Precedence(Symbol sym) { switch(sym.m_type) { case Type.Bracket: return 7; case Type.Function: return 5; case Type.UnaryOperator: return 4; case Type.Comma: return 0; } switch(sym.m_name) { case "^": return 3; case "/": case "*": case "%": return 2; case "+": case "-": return 1; } return -1; } protected Symbol Evaluate(Symbol opr, Symbol sym1) { Symbol result; result.m_name = opr.m_name + sym1.m_name; result.m_type = Type.Result; result.m_value = 0; switch(opr.m_name) { case "+": result.m_value = sym1.m_value;; break; case "-": result.m_value = -1 * sym1.m_value; break; default: result.m_type = Type.Error; result.m_name = "Undefine unary operator: " + opr.m_name + "."; break; } return result; } protected Symbol Evaluate(Symbol sym1, Symbol opr, Symbol sym2) { Symbol result; result.m_name = sym1.m_name + opr.m_name + sym2.m_name; result.m_type = Type.Result; result.m_value = 0; switch(opr.m_name) { case "^": result.m_value = System.Math.Pow(sym1.m_value,sym2.m_value); break; case "/": { if(sym2.m_value != 0) result.m_value = sym1.m_value / sym2.m_value; else { result.m_name = "Divide by Zero."; result.m_type = Type.Error; } break; } case "*": result.m_value = sym1.m_value * sym2.m_value; break; case "%": result.m_value = sym1.m_value % sym2.m_value; break; case "+": result.m_value = sym1.m_value + sym2.m_value; break; case "-": result.m_value = sym1.m_value - sym2.m_value; break; default: result.m_type = Type.Error; result.m_name = "Undefine operator: " + opr.m_name + "."; break; } return result; } protected Symbol EvaluateFunction(string name, params Object[] args) { Symbol result; result.m_name = ""; result.m_type = Type.Result; result.m_value = 0; switch(name) { case "cos": if(args.Length == 1) { result.m_name = name + "(" + ((Symbol)args[0]).m_value.ToString() + ")"; result.m_value = System.Math.Cos(((Symbol)args[0]).m_value); } else { result.m_name = "Invalid number of parameters in: "+ name +"."; result.m_type = Type.Error; } break; case "sin": if(args.Length == 1) { result.m_name = name + "(" + ((Symbol)args[0]).m_value.ToString() + ")"; result.m_value = System.Math.Sin(((Symbol)args[0]).m_value); } else { result.m_name = "Invalid number of parameters in: "+ name +"."; result.m_type = Type.Error; } break; case "tan": if(args.Length == 1) { result.m_name = name + "(" + ((Symbol)args[0]).m_value.ToString() + ")"; result.m_value = System.Math.Tan(((Symbol)args[0]).m_value); } else { result.m_name = "Invalid number of parameters in: "+ name +"."; result.m_type = Type.Error; } break; case "cosh": if(args.Length == 1) { result.m_name = name + "(" + ((Symbol)args[0]).m_value.ToString() + ")"; result.m_value = System.Math.Cosh(((Symbol)args[0]).m_value); } else { result.m_name = "Invalid number of parameters in: "+ name +"."; result.m_type = Type.Error; } break; case "sinh": if(args.Length == 1) { result.m_name = name + "(" + ((Symbol)args[0]).m_value.ToString() + ")"; result.m_value = System.Math.Sinh(((Symbol)args[0]).m_value); } else { result.m_name = "Invalid number of parameters in: "+ name +"."; result.m_type = Type.Error; } break; case "tanh": if(args.Length == 1) { result.m_name = name + "(" + ((Symbol)args[0]).m_value.ToString() + ")"; result.m_value = System.Math.Tanh(((Symbol)args[0]).m_value); } else { result.m_name = "Invalid number of parameters in: "+ name +"."; result.m_type = Type.Error; } break; case "log": if(args.Length == 1) { result.m_name = name + "(" + ((Symbol)args[0]).m_value.ToString() + ")"; result.m_value = System.Math.Log10(((Symbol)args[0]).m_value); } else { result.m_name = "Invalid number of parameters in: "+ name +"."; result.m_type = Type.Error; } break; case "ln": if(args.Length == 1) { result.m_name = name + "(" + ((Symbol)args[0]).m_value.ToString() + ")"; result.m_value = System.Math.Log(((Symbol)args[0]).m_value,2); } else { result.m_name = "Invalid number of parameters in: "+ name +"."; result.m_type = Type.Error; } break; case "logn": if(args.Length == 2) { result.m_name = name + "(" + ((Symbol)args[0]).m_value.ToString() + "'" + ((Symbol)args[1]).m_value.ToString() + ")"; result.m_value = System.Math.Log(((Symbol)args[0]).m_value,((Symbol)args[1]).m_value); } else { result.m_name = "Invalid number of parameters in: "+ name +"."; result.m_type = Type.Error; } break; case "sqrt": if(args.Length == 1) { result.m_name = name + "(" + ((Symbol)args[0]).m_value.ToString() + ")"; result.m_value = System.Math.Sqrt(((Symbol)args[0]).m_value); } else { result.m_name = "Invalid number of parameters in: "+ name +"."; result.m_type = Type.Error; } break; case "abs": if(args.Length == 1) { result.m_name = name + "(" + ((Symbol)args[0]).m_value.ToString() + ")"; result.m_value = System.Math.Abs(((Symbol)args[0]).m_value); } else { result.m_name = "Invalid number of parameters in: "+ name +"."; result.m_type = Type.Error; } break; case "acos": if(args.Length == 1) { result.m_name = name + "(" + ((Symbol)args[0]).m_value.ToString() + ")"; result.m_value = System.Math.Acos(((Symbol)args[0]).m_value); } else { result.m_name = "Invalid number of parameters in: "+ name +"."; result.m_type = Type.Error; } break; case "asin": if(args.Length == 1) { result.m_name = name + "(" + ((Symbol)args[0]).m_value.ToString() + ")"; result.m_value = System.Math.Asin(((Symbol)args[0]).m_value); } else { result.m_name = "Invalid number of parameters in: "+ name +"."; result.m_type = Type.Error; } break; case "atan": if(args.Length == 1) { result.m_name = name + "(" + ((Symbol)args[0]).m_value.ToString() + ")"; result.m_value = System.Math.Atan(((Symbol)args[0]).m_value); } else { result.m_name = "Invalid number of parameters in: "+ name +"."; result.m_type = Type.Error; } break; case "exp": if(args.Length == 1) { result.m_name = name + "(" + ((Symbol)args[0]).m_value.ToString() + ")"; result.m_value = System.Math.Exp(((Symbol)args[0]).m_value); } else { result.m_name = "Invalid number of parameters in: "+ name +"."; result.m_type = Type.Error; } break; default: if(m_defaultFunctionEvaluation != null) result = m_defaultFunctionEvaluation(name,args); else { result.m_name = "Function: "+ name +", not found."; result.m_type = Type.Error; } break; } return result; } protected bool m_bError = false; protected string m_sErrorDescription = "None"; protected double m_result = 0; protected ArrayList m_equation = new ArrayList(); protected ArrayList m_postfix = new ArrayList(); protected EvaluateFunctionDelegate m_defaultFunctionEvaluation; }}

评论