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

类别:.NET开发 点击:0 评论:0 推荐:

   作为程序设计人员经常会遇到这样的情况,需要将某个指定的字符串表达式转换为算术表达式并计算其结果.使用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;
  }
 }
}

本文地址:http://com.8s8s.com/it/it44797.htm