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