Given a syntax tree (binary), you are supposed to output the corresponding infix 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.
![]() | ![]() |
---|---|
Figure 1 | Figure 2 |
Output Specification:
For each case, print in a line the infix expression, with parentheses reflecting the precedences of the operators. Note that there must be no extra parentheses for the final expression, as is shown by the samples. 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个节点,下标记作1,其左右子树分别是8和7,即是接下来输入的第8和第7个节点,对此,便联想到了建立一个结构体node.以这个结构体来存放输入的数据,以及建立一棵二叉树。Node包括data,左子树,右子树,为了之后方便,设一个变量father存放其父节点,初始化为0(之后果然用上了)。
Node代码如下:
struct node
{
string data;
int l_child;
int r_child;
int father=0;
}a[100];
存放完成数据后,需要开始思考如何对数据进行搜索输出。可以使用dfs或者二叉树中序遍历。先考虑的是采用dfs算法 。函数的变量定位(node a [ ],int i)。i 是要访问的节点的下标。边界条件是一个点的左右子树均为空,则这时将这个点的data输出。若不在边界条件时,先去遍历左子树,从dfs(a,l)退出后,输出该点的data值,进一步进入右子树。若一个点的左子树为空而右子树不为空时(if中的条件2,条件1是左右均不为空),进入这个点的左子树会无限循环,所以要在最外层加上限制条件 i ! = -1。
对数据输出完成后,需要添加上括号,一开始完全没有思路该怎么加。经过观察发现所有的右孩子之后均被加上了括号,所以自然将括号添加至dfs(a,r)后,自然而然,将括号作为对应需要加至左孩子前。经过输出,发现一个问题:最外层一直都有两个括号。对此,用一个string s 保存输出的结果,在最后将括号去掉即可。利用substr(1,s.length()-2)。若只有一个字符输出结果为空,则进行判断,若首位不是"(",则不需要去括号。
完整代码如下,感觉自己在写这一篇的时候总是支离破碎的思路,却莫名其妙地过了
#include <bits/stdc++.h>
using namespace std;
struct node
{
string data;
int l_child;
int r_child;
int father=0;
}a[100];
int is_visited[100]={0};
string b;
int m=0;
void dfs(node a[],int i)
{
if(i!=-1)
{
int l=a[i].l_child;
int r=a[i].r_child;
if(a[i].l_child==-1&&a[i].r_child==-1)
{
b+=a[i].data;
}
else if((a[i].l_child==-1)&&(a[i].r_child!=-1)||a[i].l_child!=-1&&a[i].r_child!=-1)
{
b+="(";
dfs(a,l); //左子树遍历结束后,下层函数从这个出口退出
b+=a[i].data; //下层函数退出后,输出该节点的data
dfs(a,r); //进入该节点的右子树
b+=")";
}
}
}
int main()
{
int n;
cin>>n;
string s;
int l,r;
int i=0;
for(i=1;i<=n;i++)
{
cin>>s>>l>>r;
a[i].data=s;
a[i].l_child=l;
a[i].r_child=r;
if(l!=-1&&r!=-1)
{
a[l].father=i;
a[r].father=i;
}
else if(l==-1&&r!=-1)
{
a[r].father=i;
}
else if(l!=-1&&r==-1)
{
a[l].father=i;
}
}
int root=1;
while(a[root].father!=0)
{
root=a[root].father;
}
dfs(a,root);
if(b[0]=='(')
{
b=b.substr(1,b.length()-2);
}
cout<<b<<endl;
return 0;
}