Common Subexpression Elimination UVA
阿新 • • 發佈:2018-12-11
Common Subexpression Elimination
題目大意:給出一段表示式,並讓其中的重複部分用序號來代替
思路:首先針對表示式構建出表示式樹,對於出現過了的子樹用map儲存,再在列印時用一個vis陣列來記錄這個序號的子樹是否列印過了,如果已經列印過了,那麼就列印其序號。
AC程式碼:
#include<cstdio> #include<iostream> #include<map> #include<string> #include<cstring> using namespace std; const int size=1e6+5; struct node{ int Hash; int l; int r; string s; node(int Hash=0,int l=-1,int r=-1,string s=""):Hash(Hash),l(l),r(r),s(s){} friend bool operator<(node a,node b) { if(a.Hash!=b.Hash) return a.Hash<b.Hash; if(a.l!=b.l) return a.l<b.l; return a.r<b.r; } }Node[size]; bool vis[size]; map<node,int> mp; int p=0; int cnt; string ori; int build() { int id=cnt++; Node[id].Hash=0; Node[id].l=-1; Node[id].r=-1; Node[id].s=""; while(ori[p]>='a'&&ori[p]<='z'){ Node[id].Hash=Node[id].Hash*26+ori[p]-'a'+1; Node[id].s.push_back(ori[p]); p++; } if(ori[p]=='(') { p++; Node[id].l=build(),p++; Node[id].r=build(),p++; } if(mp.count(Node[id])){ cnt--; return mp[Node[id]]; } return mp[Node[id]]=id; } void print(int id) { if(vis[id]){ printf("%d",id+1); return ; } vis[id]=true; cout<<Node[id].s; if(Node[id].l!=-1) { printf("("); print(Node[id].l); printf(","); print(Node[id].r); printf(")"); } } int main() { int t; scanf("%d",&t); while(t--){ memset(vis,0,sizeof(vis)); p=0; cnt=0; mp.clear(); cin>>ori; print(build()); cout<<endl; } }