.Net下的算术表达式解析器的实现思路与源码

    技术2022-05-11  57

       作为程序设计人员经常会遇到这样的情况,需要将某个指定的字符串表达式转换为算术表达式并计算其结果.使用Delphi的朋友可以在网上获取第三方控件来实现,.Net框架类库并没有相关的处理类,正好在前不久的给一所大学开发的Web应用中也需要实现相关的处理.就抽空写了一个相关的处理类(实现了大部分的算术运算操作,需要其他运算可以在现有基础上扩展),现将部分代码贴出共大家参考,希望能够在交流中进步、互助中学习、探讨中深入:

    //EnumExpress

    using System;

    namespace ExpressionTest{ /// <summary> /// EnumExpress 的摘要说明。 /// </summary> public enum EnumExpress {  Add,//加号  Dec,//减号  Mul,//乘号  Div,//除号  Sin,//正玄  Cos,//余玄  Tan,//正切  ATan,//余切  Sqrt,//平方根  Pow,//求幂  None,//无 }}

    //ExpressDeal

    using System;

    namespace ExpressionTest{ /// <summary> /// ExpressDeal 的摘要说明。 /// </summary> public class ExpressDeal {  static ExpressDeal()  {     }  private double CalculateExpress(string strExpression)  {      string strTemp="";   string strTempB="";   string strOne="";   string strTwo="";   double ReplaceValue=0;   while (strExpression.IndexOf("+")!=-1 || strExpression.IndexOf("-")!=-1     || strExpression.IndexOf("*")!=-1 || strExpression.IndexOf("/")!=-1)   {    if (strExpression.IndexOf("*")!=-1)    {     strTemp=strExpression.Substring(strExpression.IndexOf("*")+1,strExpression.Length-strExpression.IndexOf("*")-1);     strTempB=strExpression.Substring(0,strExpression.IndexOf("*"));

         strOne=strTempB.Substring(GetPrivorPos(strTempB)+1,strTempB.Length-GetPrivorPos(strTempB)-1);          strTwo=strTemp.Substring(0,GetNextPos(strTemp));

         ReplaceValue=Convert.ToDouble(GetExpType(strOne))*Convert.ToDouble(GetExpType(strTwo));

         strExpression=strExpression.Replace(strOne+"*"+strTwo,ReplaceValue.ToString());    }    else if (strExpression.IndexOf("/")!=-1)    {     strTemp=strExpression.Substring(strExpression.IndexOf("/")+1,strExpression.Length-strExpression.IndexOf("/")-1);     strTempB=strExpression.Substring(0,strExpression.IndexOf("/"));

         strOne=strTempB.Substring(GetPrivorPos(strTempB)+1,strTempB.Length-GetPrivorPos(strTempB)-1);               strTwo=strTemp.Substring(0,GetNextPos(strTemp));

         ReplaceValue=Convert.ToDouble(GetExpType(strOne))/Convert.ToDouble(GetExpType(strTwo));

         strExpression=strExpression.Replace(strOne+"/"+strTwo,ReplaceValue.ToString());    }    else if (strExpression.IndexOf("+")!=-1)    {     strTemp=strExpression.Substring(strExpression.IndexOf("+")+1,strExpression.Length-strExpression.IndexOf("+")-1);     strTempB=strExpression.Substring(0,strExpression.IndexOf("+"));

         strOne=strTempB.Substring(GetPrivorPos(strTempB)+1,strTempB.Length-GetPrivorPos(strTempB)-1);          strTwo=strTemp.Substring(0,GetNextPos(strTemp));

         ReplaceValue=Convert.ToDouble(GetExpType(strOne))+Convert.ToDouble(GetExpType(strTwo));

         strExpression=strExpression.Replace(strOne+"+"+strTwo,ReplaceValue.ToString());    }    else if (strExpression.IndexOf("-")!=-1)    {     strTemp=strExpression.Substring(strExpression.IndexOf("-")+1,strExpression.Length-strExpression.IndexOf("-")-1);     strTempB=strExpression.Substring(0,strExpression.IndexOf("-"));

         strOne=strTempB.Substring(GetPrivorPos(strTempB)+1,strTempB.Length-GetPrivorPos(strTempB)-1);               strTwo=strTemp.Substring(0,GetNextPos(strTemp));

         ReplaceValue=Convert.ToDouble(GetExpType(strOne))-Convert.ToDouble(GetExpType(strTwo));

         strExpression=strExpression.Replace(strOne+"-"+strTwo,ReplaceValue.ToString());    }   }      return Convert.ToDouble(strExpression);  }    private double CalculateExExpress(string strExpression,EnumExpress ExpressType)  {   double retValue=0;   switch(ExpressType)   {    case EnumExpress.Sin:     retValue=Math.Sin(Convert.ToDouble(strExpression));     break;    case EnumExpress.Cos:     retValue= Math.Cos(Convert.ToDouble(strExpression));     break;    case EnumExpress.Tan:     retValue= Math.Tan(Convert.ToDouble(strExpression));     break;    case EnumExpress.ATan:     retValue= Math.Atan(Convert.ToDouble(strExpression));     break;    case EnumExpress.Sqrt:     retValue= Math.Sqrt(Convert.ToDouble(strExpression));     break;    case EnumExpress.Pow:     retValue= Math.Pow(Convert.ToDouble(strExpression),2);     break;   }   if (retValue==0) return Convert.ToDouble(strExpression);   return retValue;  }  private int GetNextPos(string strExpression)  {   int[] ExpPos=new int[4];   ExpPos[0]=strExpression.IndexOf("+");   ExpPos[1]=strExpression.IndexOf("-");   ExpPos[2]=strExpression.IndexOf("*");   ExpPos[3]=strExpression.IndexOf("/");   int tmpMin=strExpression.Length;   for (int count=1;count<=ExpPos.Length;count++)   {    if (tmpMin>ExpPos[count-1] && ExpPos[count-1]!=-1)    {     tmpMin=ExpPos[count-1];    }   }

       return tmpMin;     }  private int GetPrivorPos(string strExpression)  {   int[] ExpPos=new int[4];   ExpPos[0]=strExpression.LastIndexOf("+");   ExpPos[1]=strExpression.LastIndexOf("-");   ExpPos[2]=strExpression.LastIndexOf("*");   ExpPos[3]=strExpression.LastIndexOf("/");   int tmpMax=-1;   for (int count=1;count<=ExpPos.Length;count++)   {    if (tmpMax<ExpPos[count-1] && ExpPos[count-1]!=-1)    {     tmpMax=ExpPos[count-1];    }   }

       return tmpMax;     }  public string SpiltExpression(string strExpression)  {   string strTemp="";   string strExp="";

       while (strExpression.IndexOf("(")!=-1)   {    strTemp=strExpression.Substring(strExpression.LastIndexOf("(")+1,strExpression.Length-strExpression.LastIndexOf("(")-1);    strExp=strTemp.Substring(0,strTemp.IndexOf(")"));    strExpression=strExpression.Replace("("+strExp+")",CalculateExpress(strExp).ToString());

       }   if(strExpression.IndexOf("+")!=-1 || strExpression.IndexOf("-")!=-1     || strExpression.IndexOf("*")!=-1 || strExpression.IndexOf("/")!=-1)   {    strExpression=CalculateExpress(strExpression).ToString();   }   return strExpression;  }    private string GetExpType(string strExpression)  {   strExpression=strExpression.ToUpper();   if (strExpression.IndexOf("SIN")!=-1)   {    return CalculateExExpress(strExpression.Substring(strExpression.IndexOf("N")+1,strExpression.Length-1-strExpression.IndexOf("N")),EnumExpress.Sin).ToString();   }   if (strExpression.IndexOf("COS")!=-1)   {    return CalculateExExpress(strExpression.Substring(strExpression.IndexOf("S")+1,strExpression.Length-1-strExpression.IndexOf("S")),EnumExpress.Cos).ToString();   }   if (strExpression.IndexOf("TAN")!=-1)   {    return CalculateExExpress(strExpression.Substring(strExpression.IndexOf("N")+1,strExpression.Length-1-strExpression.IndexOf("N")),EnumExpress.Tan).ToString();   }   if (strExpression.IndexOf("ATAN")!=-1)   {    return CalculateExExpress(strExpression.Substring(strExpression.IndexOf("N")+1,strExpression.Length-1-strExpression.IndexOf("N")),EnumExpress.ATan).ToString();   }   if (strExpression.IndexOf("SQRT")!=-1)   {    return CalculateExExpress(strExpression.Substring(strExpression.IndexOf("T")+1,strExpression.Length-1-strExpression.IndexOf("T")),EnumExpress.Sqrt).ToString();   }   if (strExpression.IndexOf("POW")!=-1)   {    return CalculateExExpress(strExpression.Substring(strExpression.IndexOf("W")+1,strExpression.Length-1-strExpression.IndexOf("W")),EnumExpress.Pow).ToString();   }   return strExpression;  } }}


    最新回复(0)