思路见紫书第十一章例题11-1
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<map>
using namespace std;
const int maxn=50000+10;
struct node
{
string a;
int l,r;
int lu,ru;
bool operator < (const node &u) const //map操作需要用
{
if(a<u.a) return true;
if(a>u.a) return false;
if(lu<u.lu) return true;
if(lu>u.lu) return false;
if(ru<u.ru) return true;
if(ru>u.ru) return false;
return false;
}
}tree[maxn];
map<node,int> m;
int n,len;
char s[10*maxn];
int nc,p,cnt;
void build_tree() //建树
{
int root=nc;
tree[root].lu=tree[root].ru=tree[root].l=tree[root].r=-1;
tree[root].a="";
while(p<len)
{
if(s[p]=='(')
{
p++;
tree[root].l=++nc;
build_tree();
tree[root].r=++nc;
build_tree();
}
else if(s[p]==')'||s[p]==',')
{
p++;
return;
}
else tree[root].a+=s[p++];
}
}
int id[maxn];
int vis_tree(int u) //给每个树编号
{
id[u]=++cnt;
if(tree[u].l!=-1)
{
tree[u].lu=vis_tree(tree[u].l);
tree[u].ru=vis_tree(tree[u].r);
}
if(!m[tree[u]]) m[tree[u]]=id[u];
else cnt--;
return m[tree[u]];
}
bool vis[maxn];
void prt_tree(int u) //输出树
{
if(vis[m[tree[u]]]) //这个编号的树输出过了
{
cout<<m[tree[u]]; //只输出编号
return;
}
cout<<tree[u].a;
if(tree[u].l!=-1)
{
cout<<'(';
prt_tree(tree[u].l);
cout<<',';
prt_tree(tree[u].r);
cout<<')';
}
vis[m[tree[u]]]=true; //输出标记
}
int main()
{
scanf("%d",&n);
while(n--)
{
p=cnt=0;
nc=1;
scanf("%s",s);
len=strlen(s);
m.clear();
build_tree();
vis_tree(1);
memset(vis,false,sizeof(vis));
prt_tree(1);
cout<<endl;
}
return 0;
}