PAT 2019年秋季 7-3 Postfix Expression (25 分)
Given a syntax tree (binary), you are supposed to output the corresponding postfix expression, with parentheses reflecting the precedences of the operators
Input Specification:
Each input file contains one test case. For each case, the first line gives a positive integer N (≤ 20) which is the total number of nodes in the syntax tree. Then N lines follow, each gives the information of a node (the i-th line corresponds to the i-th node) in the format:
data left_child right_child
where data is a string of no more than 10 characters, left_child and right_child are the indices of this node's left and right children, respectively. The nodes are indexed from 1 to N. The NULL link is represented by −1. The figures 1 and 2 correspond to the samples 1 and 2, respectively.
Output Specification:
For each case, print in a line the postfix expression, with parentheses reflecting the precedences of the operators.There must be no space between any symbols.
Sample Input 1:
8
* 8 7
a -1 -1
* 4 1
+ 2 5
b -1 -1
d -1 -1
- -1 6
c -1 -1
Sample Output 1:
(((a)(b)+)((c)(-(d))*)*)
Sample Input 2:
8
2.35 -1 -1
* 6 1
- -1 4
% 7 8
+ 2 3
a -1 -1
str -1 -1
871 -1 -1
Sample Output 2:
(((a)(2.35)*)(-((str)(871)%))+)
实现思路:
题意是要输出静态树的后缀表达式,这里需要单独处理的情况:
1.当一个结点只有右孩子而没有左孩子的时候需要按照中序输出这个结点的结点值,例如第一个样例中的'-'号是在d之前的,其余的情况都放在传统的后序输出即可。
2.当一个结点左右孩子都存在的时候,在先序遍历输出'(',在后序遍历输出')'。
3.当一个结点左孩子为空的时候,在先序遍历输出'(',在后序遍历输出')'。
tips:有一个小细节,那就是结点数可能是双位的,不要用char来保存,用string或者char数组。
本题在PAT之前题库有出过类似题,前中后缀表达式的考题
AC代码:
#include <iostream>
#include <cstring>
using namespace std;
const int N=30;
struct node {
string x;
int l,r;
} Node[N];
void postOrder(int root) {
if(root==-1) return;
if(Node[root].l!=-1&&Node[root].r!=-1) printf("(");//左右孩子都存在的时候需要输出符号
if(Node[root].l==-1) printf("(");//当前结点左孩子不存在的时候输出
postOrder(Node[root].l);
if(Node[root].l==-1&&Node[root].r!=-1) cout<<Node[root].x;//当前结点只有右孩子的时候 这个符号需要中序输出
postOrder(Node[root].r);
if((Node[root].l==-1&&Node[root].r==-1)||(Node[root].l!=-1&&Node[root].r!=-1))
cout<<Node[root].x;
if(Node[root].l==-1) printf(")");
if(Node[root].l!=-1&&Node[root].r!=-1) printf(")");
}
int main() {
cin.tie(0);
int n,father[N]= {0},roodId; //father用于寻找根节点索引
cin>>n;
for(int i=1; i<=n; i++) {
cin>>Node[i].x>>Node[i].l>>Node[i].r;
if(Node[i].l!=-1) father[Node[i].l]=1;
if(Node[i].r!=-1) father[Node[i].r]=1;
}
for(int i=1; i<=n; i++) {
if(!father[i]) {
roodId=i;//找到根节点
break;
}
}
postOrder(roodId);
return 0;
}