【數算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 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM