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

原创 2004年05月10日 12:22:00

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

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

.Net下的算术表达式解析器的实现思路与源码 作为程序设计人员经常会遇到这样的情况,需要将某个指定的字符串表达式转换为算术表达式并计算其结果.使用Delphi的朋友可以在网上获取第三方控件来实现,而...
  • u014739770
  • u014739770
  • 2014年04月24日 12:25
  • 197

【原创】.NET开源表达式计算组件介绍与使用

本博客所有文章分类的总目录:http://www.cnblogs.com/asxinyu/p/4288836.html 本博客其他.NET开源项目文章目录:http://www.cnblogs.co...
  • asxinyu_usst
  • asxinyu_usst
  • 2016年02月20日 08:52
  • 743

表达式解析计算器源码(完整实现)

大一下时做的大数非图形界面计算器,自己在这个过程中收获较大,希望和大家分享下 分三个(面向过程浮点版,面向对象浮点版和面向对象大数版)版本:: 完整实现如下: Version1: 面向过程浮点版 (从...
  • David_Jett
  • David_Jett
  • 2015年01月27日 20:44
  • 1496

中缀算数表达式求值

【题目】中缀表示法(Infix expression),算数表达式求值1、只考虑 + - * / ( ) 这几个基本运算符,且是二元操作 2、运算数只考虑 0-9,这10个简单的数,方便从strin...
  • Tina224243
  • Tina224243
  • 2016年11月08日 12:04
  • 721

编译原理动手实操,用java实现编译器-算术表达式及其语法解析器的实现

大家在参考本节时,请先阅读以下博文,进行预热: http://blog.csdn.net/tyler_download/article/details/50708807   本节代码下载地址: htt...
  • tyler_download
  • tyler_download
  • 2016年02月26日 17:14
  • 2007

基于逆波兰表达式的公式解析器-算法和思路(一)

背景:        最近项目需要自己完成Excel的公式解析和求值,在Java中可以使用POI解析Excel公式然后求值。但是项目需要JS端和Java后端均需要支持公式解析,所以就需要自己写一套了。...
  • HackerSaillen
  • HackerSaillen
  • 2015年06月25日 14:41
  • 3872

Java数据结构和算法-栈和队列(4-解析算术表达式)

解析算术表达式,例如3+4*5等和之前所学的例子匹配分隔符类似,都是利用栈来实现的,只不过解析算术表达式会更复杂一些。 计算机算法直接求算术表达式是很难的,但是通过下面两个步骤实现算法会相对容易很多...
  • Jane_No1
  • Jane_No1
  • 2016年12月07日 11:59
  • 746

算术表达式求值 - 栈的应用

一、实验目的 1、掌握栈的定义及实现; 2、掌握利用栈求解算术表达式的方法。 二、实验内容 通过修改完善教材中的算法3.4,利用栈来实现算术表达式求值的算法。对算法3.4中调用的几个函数要给出...
  • deaidai
  • deaidai
  • 2017年05月16日 17:00
  • 1239

算数表达式求值C++实现

为了简化问题,关注算法,本文的讨论基于以下三点: 1. 只考虑 + - * / ( ) 这几个基本运算符,且是二元操作 2. 运算数只考虑 0-9,这10个简单的数,方便从string中取出来 3. ...
  • qq_26891045
  • qq_26891045
  • 2016年03月14日 21:41
  • 2935

算法 -- 双栈算术表达式求值算法

算法 – 双栈算术表达式求值算法最近在学习算法时候,看到一个双栈算术表达式求值算法,挺启发我的;平常大家在写代码的时候要写表达式的时候,基本都是直接 (1 + ( ( 2 + 3 ) * ( 4 * ...
  • erzhanchen
  • erzhanchen
  • 2017年02月26日 17:53
  • 212
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:.Net下的算术表达式解析器的实现思路与源码
举报原因:
原因补充:

(最多只允许输入30个字)