C++bulid中表达式求值

王朝c/c++·作者佚名  2006-01-08
宽屏版  字体: |||超大  

//***************************************************************************

//

// +-*/()运算表达式,函数

// 调用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

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
© 2005- 王朝网络 版权所有