//构建左子树和右子树实际每次操作返回或者写入一个子树的根节点
//构建表达式树
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
char shz[1000];
char op[1000];
int lch[1000],rch[1000];//树状数组用链表表示
int nc=0;
//找到最后运算的那一个字符建树,返回该节点写入树状数组
int build_tree(int x,int y){
int p=0,c1=-1,c2=-1,u;//c1跟踪括号外的加减号,c2跟踪乘除号,p表示是否在括号外
if(y-x==1){
//到了最后一个元素
u=++nc;//保存当前结点在现在的子树的位置
op[u]=shz[x];
lch[u]=rch[u]=0;
// cout<<u<<" test u"<<endl;
return u;//返回给上一层子树的子节点,当前子树的根节点
}
for(int i=x;i<y;i++){//寻找运算优先级最低的那个运算符 此处注意迭代边界
if(shz[i]=='(')p++;
if(shz[i]==')')p--;
if(shz[i]=='+'||shz[i]=='-'){
if(!p)c1=i;
// cout<<" jdfai"<<endl;
}
if(shz[i]=='*'||shz[i]=='/'){
if(!p)c2=i;
}
// cout<<i<<" "<<p<<" "<<c1<<" "<<c2<<" test i p c1 c2"<<endl;
}
// int a;
// cin>>a;
// cout<<c1<<" "<<c2<<" test c1 c2"<<endl;
//去最后的运算符作为子树的根节点,括号内的忽略,括号外的加减号比乘除号的运算级低
if(c1<0)c1=c2;
if(c1<0)return build_tree(x+1,y-1);//如果被一个左闭右开区间被一个括号围着,除去括号,出去两边字符的方法用递归(x++,y++)
u=++nc;
op[u]=shz[c1];
lch[u]=build_tree(x,c1);
// cout<<" adf"<<endl;
rch[u]=build_tree(c1+1,y);//递归找寻子树的根节点返回给当前子树 作为子节点
// cout<<u<<" Test u"<<endl;
return u;//要使一个递归能够完成两个递归分支或者更多,并且有返回追,那么return u必须在最后 return u 返回给上一个节点的子节点,当前子树的根节点,决定是左还是右在于递归是参数的折半分割。
}
int main(){
while(scanf("%s",shz)!=EOF){
// cout<<strlen(shz)<<endl;
int root=build_tree(0,strlen(shz));
cout<<root<<" the root of the tree"<<endl;
for(int i=root;i<=nc;i++){
cout<<i<<" "<<op[i]<<" "<<lch[i]<<" "<<rch[i]<<endl;
}
}
}
//构建表达式树
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
char shz[1000];
char op[1000];
int lch[1000],rch[1000];//树状数组用链表表示
int nc=0;
//找到最后运算的那一个字符建树,返回该节点写入树状数组
int build_tree(int x,int y){
int p=0,c1=-1,c2=-1,u;//c1跟踪括号外的加减号,c2跟踪乘除号,p表示是否在括号外
if(y-x==1){
//到了最后一个元素
u=++nc;//保存当前结点在现在的子树的位置
op[u]=shz[x];
lch[u]=rch[u]=0;
// cout<<u<<" test u"<<endl;
return u;//返回给上一层子树的子节点,当前子树的根节点
}
for(int i=x;i<y;i++){//寻找运算优先级最低的那个运算符 此处注意迭代边界
if(shz[i]=='(')p++;
if(shz[i]==')')p--;
if(shz[i]=='+'||shz[i]=='-'){
if(!p)c1=i;
// cout<<" jdfai"<<endl;
}
if(shz[i]=='*'||shz[i]=='/'){
if(!p)c2=i;
}
// cout<<i<<" "<<p<<" "<<c1<<" "<<c2<<" test i p c1 c2"<<endl;
}
// int a;
// cin>>a;
// cout<<c1<<" "<<c2<<" test c1 c2"<<endl;
//去最后的运算符作为子树的根节点,括号内的忽略,括号外的加减号比乘除号的运算级低
if(c1<0)c1=c2;
if(c1<0)return build_tree(x+1,y-1);//如果被一个左闭右开区间被一个括号围着,除去括号,出去两边字符的方法用递归(x++,y++)
u=++nc;
op[u]=shz[c1];
lch[u]=build_tree(x,c1);
// cout<<" adf"<<endl;
rch[u]=build_tree(c1+1,y);//递归找寻子树的根节点返回给当前子树 作为子节点
// cout<<u<<" Test u"<<endl;
return u;//要使一个递归能够完成两个递归分支或者更多,并且有返回追,那么return u必须在最后 return u 返回给上一个节点的子节点,当前子树的根节点,决定是左还是右在于递归是参数的折半分割。
}
int main(){
while(scanf("%s",shz)!=EOF){
// cout<<strlen(shz)<<endl;
int root=build_tree(0,strlen(shz));
cout<<root<<" the root of the tree"<<endl;
for(int i=root;i<=nc;i++){
cout<<i<<" "<<op[i]<<" "<<lch[i]<<" "<<rch[i]<<endl;
}
}
}