UVA-12219 Common Subexpression Elimination

思路见紫书第十一章例题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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值