【数算A】表达式·表达式树·表达式求值

这道题在输出上太坑了,画出来不像树...

  1 #include<iostream>
  2 #include<cstring>
  3 #include<stack>
  4 using namespace std;
  5 int val[26],n,len,ans,maxDep;
  6 char infix[55],postfix[55],out[50][300];
  7 struct node{
  8     int ch;
  9     node *l,*r;
 10     node(){
 11         l=r=NULL;
 12     }
 13 }*root;
 14 //计算a^b 
 15 int pow(int a,int b){
 16     int res=1;
 17     for(int i=1;i<=b;i++)
 18         res*=a;
 19     return res; 
 20 }
 21 //将中缀转化为后缀表达式 
 22 void infixToPost(char *s){
 23     len=strlen(s);
 24     int i=0;
 25     stack<char> S;
 26     for(int j=0;j<len;j++){
 27         if(isalpha(s[j])) postfix[i++]=s[j];
 28         else if(s[j]=='(') S.push(s[j]);
 29         else if(s[j]==')'){
 30             while(!S.empty()&&S.top()!='('){
 31                 postfix[i++]=S.top();
 32                 S.pop();
 33             }
 34             if(!S.empty()) S.pop();
 35         }
 36         else{
 37             while(!S.empty()&&S.top()!='('&&(s[j]=='+'||s[j]=='-'||S.top()=='*'||S.top()=='/')){
 38                 postfix[i++]=S.top();
 39                 S.pop();
 40             }
 41             S.push(s[j]);
 42         }
 43     }
 44     while(!S.empty()){
 45         postfix[i++]=S.top();
 46         S.pop();
 47     }
 48     postfix[i]=0;
 49     len=i;          //把len设置为postfix的长度 
 50 }
 51 //根据建的树求值 
 52 int cal(node *cur){
 53     if(isalpha(cur->ch)) return val[cur->ch-'a'];
 54     else{
 55         switch(cur->ch){
 56             case '+':return cal(cur->l)+cal(cur->r);
 57             case '-':return cal(cur->l)-cal(cur->r);
 58             case '*':return cal(cur->l)*cal(cur->r);
 59             case '/':return cal(cur->l)/cal(cur->r);
 60         }
 61     }
 62 }
 63 //找到树的高度 
 64 int findDep(node *cur){
 65     if(!cur) return 0;
 66     int l=findDep(cur->l);
 67     int r=findDep(cur->r);
 68     return l>r?l+1:r+1;
 69 }
 70 //将要打印的内容输出到out中 
 71 void print(node *cur,int x,int y,int space){
 72      out[x][y]=cur->ch;
 73      if(cur->l){
 74          out[x+1][y-1]='/';
 75          print(cur->l,x+2,y-space,space>>1);
 76      }
 77      if(cur->r){
 78          out[x+1][y+1]='\\';
 79          print(cur->r,x+2,y+space,space>>1);
 80      }
 81 }
 82 //打印树 
 83 void printTree(){
 84     //我们已经知道m层的树有2m-1层输出,所以直接利用这一点即可(out[]的输出范围为0~2m-2) 
 85     for(int i=0;i<2*maxDep-1;i++){
 86         int j=299;
 87         while(out[i][j]==' ') j--;
 88         out[i][j+1]=0; 
 89         cout<<out[i]<<endl;
 90     }
 91 }
 92 //建树 
 93 void build(){
 94     stack<node*> S;
 95     for(int i=0;i<len;i++){
 96         node *t=new node;
 97         t->ch=postfix[i];
 98         if(!isalpha(t->ch)){
 99             t->r=S.top();S.pop();
100             t->l=S.top();S.pop();
101         }
102         S.push(t);
103     }
104     root=S.top();S.pop();
105 }
106 int main()
107 {
108     cin>>infix;
109     cin>>n;
110     while(n--){
111         char ch;
112         int v;
113         cin>>ch>>v;
114         val[ch-'a']=v;
115     }
116     infixToPost(infix);         //中缀转后缀 
117     cout<<postfix<<endl;
118     build();                    //根据后缀建树 
119     ans=cal(root);              //计算值 
120     maxDep=findDep(root);       //得到最大深度 
121     memset(out,' ',sizeof(out));
122     //注意到根结点一定是在第一行的2^(maxDep-1)-1的下标位置(别问为什么,因为你看输出出来就是这么诡异),
123     //也就是位于中间的位置,再根据当前层数判断叶子结点放的位置(print函数中)
124     int y=pow(2,maxDep-1)-1;    //根结点在y上的坐标 
125     print(root,0,y,y+1>>1);     //形成树形图
126     printTree();
127     cout<<ans;
128 }

 

posted @ 2017-12-03 15:50  sulley  阅读(1854)  评论(1编辑  收藏  举报