PAT(甲級)2019年秋季考試 7-3 Postfix Expression

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.node

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:ios

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.算法

infix1.JPG
Figure 1
infix2.JPGexpress

Figure 2數組

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.post

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)%))+)

題目限制:

image.png

題目大意:

現給定一顆語法樹,要求輸出其後綴表達式。this

算法思路:

後綴表達式實際上就是將a+b的操做符移到最後變爲ab+,可是存在特殊狀況,由於+和-既能夠表明加減法,又能夠表明正負號,因此這裏得判斷+,-是不是和後面的數字綁定在一塊兒做爲符號位的,判斷的方法就是當前的左孩子是否爲空,若是爲空,那麼就說明當前節點的操做符是一個符號位,和右子樹的數值是一個總體。不然就是正常的先訪問左子樹,後訪問右子樹,最後訪問操做符。
綜上所述:spa

  • 一、若是當前節點沒有左孩子,遍歷根節點,而後再遍歷右子樹
  • 二、若是有左孩子,進行後序遍歷。

而後就是對於該數根節點的獲取,使用parent數組保存每個節點的根節點,初始爲0,只要輸入完畢後,其parent值依然爲0的,就是根節點。最後進行後序遍歷輸出便可。3d

注意點:

  • 一、因爲題目說了該樹是一個語法樹,不存在一個操做符爲二元操做符,而且尚未左孩子的狀況,也就是說沒有左孩子的時候就必定是單元操做符。
  • 二、括號的輸出是針對整個子樹的,分三種狀況,葉子節點,輸出爲(節點值),沒有左孩子,輸出爲(根節點,右子樹),有左孩子,輸出爲(左子樹,右子樹,根節點)

提交結果:

image.png

AC代碼:

#include<cstdio>
#include<vector>
#include<iostream>

using namespace std;

struct Node{
    string c;
    int left,right;
}node[30];

int parent[30];

void postOrder(int root){
    if(root==-1) return;
    printf("(");
    if(node[root].left==-1){
        // 只有右子樹,先輸出當前節點,再輸出右子樹
        printf("%s",node[root].c.c_str());
        postOrder(node[root].right);
        printf(")");
    }else{
        // 左右子樹都有,正常後序遍歷便可
        postOrder(node[root].left);
        postOrder(node[root].right);
        printf("%s)",node[root].c.c_str());
    }
}

int main(){
    int N;
    scanf("%d",&N);
    Node no;
    for(int i=1;i<=N;++i){
        cin>>no.c>>no.left>>no.right;
        node[i] = no;
        parent[no.left] = i;
        parent[no.right] = i;
    }
    int root;
    for(int i=1;i<=N;++i){
        if(parent[i]==0){
            root = i;
            break;
        }
    }
    postOrder(root);
    return 0;
}
相關文章
相關標籤/搜索