表达式求值问题之表达式树

来源:互联网 发布:java设计模式分类 编辑:程序博客网 时间:2024/05/21 05:08
#include<iostream>#include<cstdio>#include<string.h>#include<stack>#define M 1005#define CLR(arr,now) memset(arr,now,sizeof(arr))using namespace std;stack<double>shu;typedef struct Node{char ope[10];struct Node *lchild,*rchild;Node(){CLR(ope,'\0');lchild=rchild=NULL;}}*Tire,T;char str[M];char pre[M],post[M];int prelen,postlen,pos;Tire build(int l,int r)//建立表达式树{if(l>r) return 0;if(str[l]>='0'&&str[1]<='9'||str[l]=='.'){double temp;int len;sscanf(&str[l],"%lf%n",&temp,&len);//从字符串中读取信息到temp和lenif(l+len-1==r){Tire cur=new T;sprintf(cur->ope,"%lf",temp);cur->ope[len]='\0';cur->lchild=cur->rchild=NULL;return cur;}}int pos=0,optr1=-1,optr2=-1;for(int i=l;i<=r;++i){switch(str[i]){case '(':pos++;break;case ')':pos--;break;case '+':case '-':if(pos==0) optr1=i;break;case '*':case '/':if(pos==0) optr2=i;break;}}if(optr1==-1) optr1=optr2;if(optr1==-1) return build(l+1,r-1);Tire cur=new T;cur->ope[0]=str[optr1];cur->ope[1]='\0';cur->lchild=build(l,optr1-1);cur->rchild=build(optr1+1,r);return cur;}void pre_order(Tire root)//中缀转化为前缀式{if(root!=NULL){sprintf(&pre[prelen],"%s",root->ope);prelen+=strlen(root->ope);pre[prelen++]=' ';pre_order(root->lchild);pre_order(root->rchild);    }}void post_order(Tire root)//中缀转化为后缀式{if(root!=NULL){post_order(root->lchild);post_order(root->rchild);sprintf(&post[postlen],"%s",root->ope);postlen+=strlen(root->ope);post[postlen++]=' ';}}double pre_calucate()//前缀表达式计算{     pos++;   if(pre[pos]==' ') pos++;   if(pre[pos]>='0'&&pre[pos]<='9')   {   double temp;   int len;   sscanf(&pre[pos],"%lf%n",&temp,&len);   pos+=len-1;   return temp;   }   if(pre[pos]=='+') return pre_calucate()+pre_calucate();   if(pre[pos]=='-') return pre_calucate()-pre_calucate();   if(pre[pos]=='/') return pre_calucate()/pre_calucate();   if(pre[pos]=='*') return pre_calucate()*pre_calucate();  }double post_calucate()//后缀表达式计算{postlen=strlen(post)-1;for(int i=0;i<postlen;++i){if(post[i]>='0'&&post[i]<='9'){double temp;int len;sscanf(&post[i],"%lf%n",&temp,&len);i+=len-1;shu.push(temp);}else if(post[i]==' ') continue;else{double a=shu.top();shu.pop();double b=shu.top();shu.pop();if(post[i]=='+') shu.push(a+b);if(post[i]=='-') shu.push(b-a);if(post[i]=='*') shu.push(b*a);if(post[i]=='/') shu.push(b/a);}}double k=shu.top();shu.pop();return k;}void delet(Tire root)//销毁表达式树{if(root->lchild) delet(root->lchild);if(root->rchild) delet(root->rchild);delete root;}int main(){  // freopen("1.txt","r",stdin);   // freopen("2.txt","w",stdout);  int T;  cin>>T;while(T--){    pos=-1;   CLR(pre,'\0');   CLR(post,'\0');       scanf("%s",str);prelen=0,postlen=0;int n=strlen(str);Tire root=build(0,n-2);pre_order(root);post_order(root);cout<<pre<<"="<<endl;        cout<<post<<"="<<endl;//printf("%.2lf\n",pre_calucate());printf("%.2lf\n",post_calucate());        delet(root);}return 0;}