Common Subexpression Elimination UVA - 12219

点击打开链接


#include<bits/stdc++.h>

using namespace std;

const int maxn=6e4+10;

char str[maxn*10],* p;

/*
map容器的处理规则就是:只要关键比较键值不相等,map就会将此节点添加进map容器里,与其他属性无关。
所以如果是只写第一句话的话,只要score想等,就不会比较别的了,所以要注意 
*/
struct node{
    int hash_val;
    string s;
    int ls,rs;
    bool operator<(const node& b)const{//放到map里需要 重载 <
    	//return hash_val<b.hash_val;
    	if(hash_val!=b.hash_val)return hash_val<b.hash_val;
    	if(ls!=b.ls) return ls<b.ls;
    	return rs<b.rs;
	}
}ss[maxn*4];//??

map<node,int> ID;

int cnt;
int solve(){
	
  int id=cnt++;
  
  ss[id].ls=-1,ss[id].rs=-1;
  ss[id].s="";
  ss[id].hash_val=0;

  while(p&&isalpha(*p)){
    ss[id].hash_val=ss[id].hash_val*27+(*p)-'a'+1;//为了快速查找
    ss[id].s+=*p;//为了输出答案
    p++;
  }

  if(p&&(*p)=='('){
        p++;
        ss[id].ls=solve();
        p++;//跳过,
        ss[id].rs=solve();
        p++;
  }
 // printf("id:%d\n",id);
  //cout<<ss[id].s<<endl;
  
  if(ID.count(ss[id])){
        cnt--;
        return ID[ss[id]];
  }
  return ID[ss[id]]=id;
}

int kase;
int exi[maxn];
void  print(int v){
    if(exi[v]!=kase){
    	exi[v]=kase;
        cout<<ss[v].s;
        if(ss[v].ls!=-1){
        	printf("(");
        	print(ss[v].ls);
        	printf(",");
        	print(ss[v].rs);
        	printf(")");	
		}
    }
    else{
        cout<<v;
	}
}
/*
3
this(is(a,tiny),tree)
a(b(f(a,a),b(f(a,a),f)),f(b(f(a,a),b(f(a,a),f)),f))
z(zz(zzzz(zz,z),zzzz(zz,z)),zzzz(zz(zzzz(zz,z),zzzz(zz,z)),z))
*/
int main(){
    int T;
    scanf("%d",&T);
    for(kase=1;kase<=T;kase++){
    	ID.clear();
        scanf("%s",str);
        p=str;
        cnt=1;
        int tmp=solve();
		//printf("tmp:%d\n",tmp);
		print(tmp);
		cout<<endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_36424540/article/details/80636733