表達式樹的輸出與求值


 


 

 

 

輸入格式:

第一行給出節點的個數N,每個節點的編號為0 ~ N-1
接下來N行每行分別給出:
該節點的編號、該節點的操作數/操作符、該節點的左孩子編號、右孩子編號(-1表示NULL)


輸出格式:


第一行輸出該表達式樹的中綴表達式,該用括號的地方需要用括號括起來。
第二行輸出該表達式樹的計算結果,保留兩位小數。


樣例輸入:

11
0 - 1 2
1 + 3 4
2 / 5 6
3 4 -1 -1
4 * 7 8
5 6 -1 -1
6 3 -1 -1
7 1 -1 -1
8 - 9 10
9 5 -1 -1
10 2 -1 -1


樣例輸出:
(4+(1*(5-2)))-(6/3)

 

分析:顯然直接用中序遍歷一下樹,就可以得到中綴表達式

 void inOrder(Node* root){      if(root==NULL) return;     printf("(");      if(root->lchild!=NULL) inOrder(root->lchild);      printf("%c",root->data);      if(root->rchild!=NULL) inOrder(root->rchild);      printf(")");  }

 

 

但發現問題了,這和樣例輸出不一樣。 

仔細分析后發現,當該結點是操作數(即葉子結點)時不需要加括號。 

 修改后:

 

 1 void inOrder(Node* root){  2     if(root==NULL) return;  3     if(root->lchild==NULL && root->rchild==NULL) printf("%c",root->data);  4     else{  5         printf("(");  6         if(root->lchild!=NULL) inOrder(root->lchild);  7         printf("%c",root->data);  8         if(root->rchild!=NULL) inOrder(root->rchild);  9         printf(")"); 10  } 11 }

 

 

有點像了! 但外層多了一對括號,這是因為根節點也不需要填括號。

所以再次更改,這次引入一個layer變量,記錄結點的層數,如果layer>0則需要輸出括號。

 1 void inOrder(Node* root,int layer){  2     if(root==NULL) return;  3     if(root->lchild==NULL && root->rchild==NULL) printf("%c",root->data);  4     else{  5         if(layer>0) printf("(");  6         if(root->lchild!=NULL) inOrder(root->lchild,layer+1);  7         printf("%c",root->data);  8         if(root->rchild!=NULL) inOrder(root->rchild,layer+1);  9         if(layer>0) printf(")"); 10  } 11 }

 

 

問:如果要計算表達式的值,保留兩位小數? 

思路:遞歸解決,每次取兩個操作數,和一個操作符運算。

完整代碼如下:

 1 /**  2 * Copyright(c)  3 * All rights reserved.  4 * Author : Mered1th  5 * Date : 2019-02-23-16.40.52  6 * Description : zhongzhui  7 */
 8 #include<cstdio>
 9 #include<cstring>
10 #include<iostream>
11 #include<cmath>
12 #include<algorithm>
13 #include<string>
14 #include<unordered_set>
15 #include<map>
16 #include<vector>
17 #include<set>
18 using namespace std; 19 int N; 20 const int maxn=1010; 21 struct Node{ 22     char data; 23     Node* lchild; 24     Node* rchild; 25 }nodes[maxn]; 26 
27 void inOrder(Node* root,int layer){ 28     if(root==NULL) return; 29     if(root->lchild==NULL && root->rchild==NULL) printf("%c",root->data); 30     else{ 31         if(layer>0) printf("("); 32         if(root->lchild!=NULL) inOrder(root->lchild,layer+1); 33         printf("%c",root->data); 34         if(root->rchild!=NULL) inOrder(root->rchild,layer+1); 35         if(layer>0) printf(")"); 36  } 37 } 38 
39 double calc(double a, double b, char op) { 40     switch (op) { 41         case '+': return a + b; 42         case '-': return a - b; 43         case '*': return a * b; 44         case '/': return a / b; 45  } 46 } 47 double calculateExprTree(Node* root) { 48     if (root == NULL) return 0; 49     if (root->lchild == NULL && root->rchild == NULL) { 50       //葉節點,節點存放的是操作數
51       return root->data - '0'; 52 } 53     //非葉結點,節點存放的是操作符
54     double a = calculateExprTree(root->lchild); //遞歸計算其左子樹 55     double b = calculateExprTree(root->rchild); //遞歸計算其右子樹 56     return calc(a, b, root->data); //返回結果 57 } 58 
59 int main(){ 60 #ifdef ONLINE_JUDGE 61 #else
62     freopen("1.txt", "r", stdin); 63 #endif
64     scanf("%d",&N); 65  getchar(); 66 // Node* nodes=new Node[N];
67     int index,l,r; 68     char data; 69     for(int i=0;i<N;i++){ 70         scanf("%d %c %d %d",&index,&data,&l,&r); 71         nodes[index].data=data; 72         if(l==-1) nodes[index].lchild=NULL; 73         else nodes[index].lchild=&nodes[l]; 74         if(r==-1) nodes[index].rchild=NULL; 75         else nodes[index].rchild=&nodes[r]; 76  } 77     Node* root=&nodes[0]; 78 
79     inOrder(root,0); 80     printf("\n"); 81     double ans=calculateExprTree(root); 82     printf("%.2f",ans); 83     return 0; 84 }

參考:http://blog.csdn.net/liqiutuyuan


免責聲明!

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



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