//*************************************************************************** // // +-*/()运算表达式,函数 // 调用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

|