C++bulid中表达式求值

原创 2003年04月09日 09:56:00

//***************************************************************************
//
// +-*/()运算表达式,函数
// 调用ExpCalc(AnsiString pexpr,bool &pt)
// 输入pexpr,bool型 pt;
// 如果表达式子无误,pt为true,并返回计算结果
/*
   设计思想按"算符优先法",参考严蔚敏和吴伟民的数据结构45页算法;

*/
//


#ifndef ExpcalacH
#define ExpcalacH
//---------------------------------------------------------------------------
#include <vcl.h>
#include <stack>  //使用了stl的栈
using namespace std;
bool  findnumber(AnsiString pexpr,int pos,AnsiString &pnumber,int &i)
{
  /****************************************
   功能:将一个表达式中的数字串取出,
   pexpr是表达式,pos是起始位置,pnumber是取得数字串;
   成功了是返回true,没有数字串返回false;

   总体办法:是设定数值串-+0123456789后,将pexpr的每个字符和数值串进行判断子串;
   如果在pexpr中就放入pnumber中;注意+-.(表示正负符号)只能出现一次;

  *****************************************/
   AnsiString numset="-+.0123456789";    //设定数值串的具体值
   AnsiString tems=pexpr;
   i=pos;
   int pad=1;                           //统计加减出现次数;
   int ppos;
   int pdepo=1;                        //统计小数点出现次数;
   int padnum=1;
   int pdeponum=2;
   pnumber="";                        //将pnumber初始;
   int first=numset.Pos(tems[i]);
   if (first==1||first==2)
       padnum=2;
   if (first==3)
      pdeponum=2;
   while((ppos=numset.Pos(tems[i]))>0 && i<=tems.Length()&&pad<=padnum &&pdepo<=pdeponum) //当找到并+-符号出现小于2次
      {


       if(ppos<3)                      //是+ - 符号 位置1,2
         {
         pad++;
         if (pad>padnum)
         break;
         }
       if(ppos==3)                      //.符号3
         {
          pdepo++;
          if (pdepo>pdeponum)
             break;
         }
       pnumber=pnumber+tems[i];    //+ - .符号出现二次了
       i++;


      }
    //

   if (i==pos)                          //当启示位置和结束位置相等表示没有数值被取到
      return false;
   if (pnumber.Length()==1&&numset.Pos(pnumber[1])<4)  //"+" or "-" or "."
      return false;
   if (pnumber.Length()==2&&numset.Pos(pnumber[1])<3&&numset.Pos(pnumber[2])==3 )//"+." or "-."
      return false;
   return true;


}

 

 

int  Readsubstr(AnsiString pexpr,int pos, AnsiString &psubstr,int &i,bool&cg,int state)

{
  /* ***************************************************************
  *返回0--表示是数值,1--是运算符,2--表示无法识别取得的类型
  * state表示+-在数字前是否看作正负号;
  * i无楞成功与否是i=到下一个单词第一位置;
  *****************************************************************/
  AnsiString opertset ="()+-*/#";
  AnsiString opad="+-";
  AnsiString tems=pexpr;
  i=pos;
  psubstr="";
  cg=false;

  if (state==0)
   {
   if(findnumber(tems,pos,psubstr,i))
      {
        cg=true;
        return 0;
      }
      psubstr="";
      i=pos;
   if(opertset.Pos(tems[i])>0)
      {
       psubstr+=tems[i];
       i++;
       cg=true;
       return 1;
      }
   }
  else
   {
     i=pos;
   if(opertset.Pos(tems[i])>0)
     {
       psubstr+=tems[i];
       i++;
       cg=true;
       return 1;
     }
      psubstr="";
      i=pos+1;
   if(findnumber(tems,pos,psubstr,i))
     {
        cg=true;
        return 0;
     }

   }
  i=pos+1;
  return 2;


}

int precede(AnsiString opt1, AnsiString opt2)
{
   int oopower[7][7]=
   {
     //-------------------------- -
    //  / optr2
    //      算符优先关系表          |
   //opt1/  + - * / ( ) #         |
   //-----------------------------
  /*+*/    {2,2,0,0,0,2,2},

  /*-*/    {2,2,0,0,0,2,2},

  /* * */  {2,2,2,2,0,2,2},

  /*/*/    {2,2,2,2,0,2,2},

  /*(*/    {0,0,0,0,0,1,-1},

  /*)*/    {2,2,2,2,-1,2,2},

  /*#*/    {0,0,0,0,0,-1,1},
   } ;

  AnsiString opertset ="+-*/()#";
  int x=opertset.Pos(opt1);
  int y=opertset.Pos(opt2);
  return  oopower[x-1][y-1];
}

//----------------------------------------------------------------------------

/*
  计算a+b,a-b,a*b,a/b的值


*/
float  Operate(float a, AnsiString oper, float b)
{
   AnsiString opertset ="+-*/";
     switch (opertset.Pos(oper))
       {
         case 1:
          return a+b;

         case 2:
          return a-b;

         case 3:
          return a*b;

         case 4:
          return a/b;

       }
}

//---------------------------------------------------------------------------


/**********************************************
 输入pexpr,bool型 pt;
 如果表达式子无误,pt为true,并返回计算结果
***********************************************/
float ExpCalc(AnsiString pexpr,bool &pt)
{
  pt=true;
  AnsiString opertset="+-*/()#";
  AnsiString tems=pexpr+"#";
 
  stack <AnsiString> optr;
  stack <float> opnd;
  AnsiString theta;
  optr.push("#");
  AnsiString w;
  int pos=1;
  int i;
  bool cg=false;
  int oplx=Readsubstr(tems,pos,w,i,cg,0);
  if(!pt)
  return -10000;
  int power;
  float a,b;
  while (/*!(w.Pos("#")==1 && optr.top().Pos("#")==1)&& */ i<=tems.Length()+1)
    {
       switch (oplx)
        {
         case 0 : //"数值"
           opnd.push(StrToFloat(w));
           pos=i;
           if(i<tems.Length())
             {
               oplx=Readsubstr(tems,pos,w,i,pt,1);
               if(!pt)
                return -10000;
             }
              else
              {
                w="#" ;
                oplx=1;
                i++;
              }


           break;
         case 1: //"运算符"
           {

              power=precede(optr.top(),w);
            

              switch (power)
                  {
                    case -1: //)( ,#),(# 出现
                      return -10000.00;
                    case 0: //"<"
                       optr.push(w);
                       pos=i;
                       if(i<tems.Length())
                         {

                             oplx=Readsubstr(tems,pos,w,i,pt,0);
                             if(!pt)
                             return -10000;
                   
                          }
                       else
                         {
                              w="#" ;
                              oplx=1;
                              i++;
                         }

                       break;
                    case 1: //"="

                       optr.pop();
                       pos=i;
                       if(i<tems.Length())
                         {
                           oplx=Readsubstr(tems,pos,w,i,pt,1);
                           if(!pt)
                           return -10000;
                         }

                       else
                          {
                             w="#" ;
                             oplx=1;
                             i++;
                          }

                       break;
                    case 2: //">"
                       if(optr.empty())
                         {
                          pt=false;
                         return 10000;
                         }
                       theta=optr.top();
                       optr.pop();
                       if(opnd.empty())
                         {
                          pt=false;
                          return 10000;
                         }
                       b=opnd.top();
                       opnd.pop();
                        if(opnd.empty())
                         {
                          pt=false;
                          return 10000;
                         }
                       a=opnd.top();
                       opnd.pop();
                       opnd.push(Operate(a,theta,b));


                     
                       pos=i;
                    

                       break;

                  }

                break;

           }

         case 2: //有不可识别的;
           return -10000;
        }

    }
  pt=true;
  return opnd.top() ;
}

#endif

 

C++实现中缀表达式求值代码

给出中缀表达式字符串,求出值。
  • qin_huang
  • qin_huang
  • 2014年04月17日 20:08
  • 2809

在C++中使用栈来把中缀表达式转换为后缀表达式并求值,简单明了

#include #include//头文件包含atoi()函数 using namespace std; typedef char T; class stack{ T data[1...
  • qq_33764934
  • qq_33764934
  • 2016年07月12日 18:31
  • 1803

C语言 实现中缀表达式转后缀表达式并求值

大一菜鸟,初学编程,这是我的第一篇博客,希望能用博客记录我的成长之路。 初学数据结构,刚接触链表和栈,看到有中缀表达式转后缀的题就试着实现了一下。下面贴上代码。因为使用的是字符型变量,所以只能计算个位...
  • wait_nothing_alone
  • wait_nothing_alone
  • 2016年04月16日 18:48
  • 1693

算数表达式求值(C实现)

  • 2017年05月05日 21:49
  • 610KB
  • 下载

用C++编写的强悍&quot;表达式&quot;求值源代码

  • 2007年10月26日 22:42
  • 3KB
  • 下载

java、c++表达式求值(带括号和小数点)

  • 2015年05月04日 10:58
  • 9KB
  • 下载

C/C++表达式求值实验报告

  • 2013年11月19日 17:45
  • 77KB
  • 下载

中缀表达式求值(C++ 含合法性检查,多位数,浮点数)

  • 2010年04月05日 23:27
  • 4KB
  • 下载

C++语言实现:输入表达式字符串,求值

  • 2009年12月23日 11:18
  • 15KB
  • 下载

C++算术表达式求值(支持函数)

  • 2014年05月16日 17:47
  • 520KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C++bulid中表达式求值
举报原因:
原因补充:

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