1. 程式人生 > >表達式樹(公共表達式消除 uva 12219)

表達式樹(公共表達式消除 uva 12219)

ret esp while 利用 例如 scan n) return 表達式

2.解題思路:第一步是構造表達式樹,構造時可以利用一個map來記錄出現的子樹,並為之編號。例如,用(a,0,0)可以表示一個葉子a,用(b,3,6)表示根的名字是b,子樹的編號分別是3,6的樹。這樣既可方便地得到最簡表達式。本題總的時間復雜度為O(N*logN)。

#include<stdio.h>
#include<iostream>
#include<map>
#include<string.h>
#include<string>
using namespace std;

string s;
int k,cnt;
map<int,int>done;

struct tree
{
string s;
int ls,rs;
bool operator < (const tree& rhs) const
{
if(s!=rhs.s) return s<rhs.s;
else if(ls!=rhs.ls) return ls<rhs.ls;
else return rs<rhs.rs;
}
};

map<tree,int>tu;
map<int,tree>node;

int solve()
{
string cur;
while(s[k]>=‘a‘&&s[k]<=‘z‘) cur.push_back(s[k++]);
int id=++cnt;
tree& t=node[id];
t.s=cur;
t.ls=0;
t.rs=0;
if(s[k]==‘(‘)
{
k++;
t.ls=solve();k++;
t.rs=solve();k++;
}
if(tu[t]) {
cnt--;
return tu[t];
}
else return tu[t]=id;
}
void print(int u)
{
if(done[u]) printf("%d",u);
else
{
done[u]=1;
//printf("%d",node[u].s);
cout<<node[u].s;
if(node[u].ls)
{
printf("(");
print(node[u].ls);
printf(",");
print(node[u].rs);
printf(")");
}
}
}

int main()
{
int q;
scanf("%d",&q);
while(q--)
{
tu.clear();
done.clear();
node.clear();
cnt=k=0;
cin>>s;
print(solve());
printf("");
}
return 0;
}

表達式樹(公共表達式消除 uva 12219)