[hash 表达式树]UVa12219 - Common Subexpression Elimination

来源:互联网 发布:李毅吧吧主是谁 知乎 编辑:程序博客网 时间:2024/06/05 14:55

将每一个结点用一个三元组来表示,然后映射到map中以去重 。 其中三元组中有一个string , 我们可以用hash来处理这个string 。

因为string最大长度为4, 所以我们可以这样处理 : int hash = 0;    hash = hash * 27 + s[i] - ‘0‘ + 1; 

将hash每次乘以27 是因为字符串只有小写字母,这样做可以完美的去重 ,保证了哈希表不会重复

#include<bits/stdc++.h>using namespace std;const int maxn = 60000;int n,m,kase,cnt,done[maxn];char s[maxn * 5], *p;struct node{    string s;    int hash,l,r;    bool operator < (const node & u) const {        if(hash != u.hash) return hash < u.hash;        if(l != u.l) return l < u.l;        return r  < u.r;    }}nodes[maxn];map<node,int> dict;int parse(){    int id=cnt++;    node & u = nodes[id];    u.l=u.r=-1;    u.s="";    u.hash=0;    while(isalpha(*p)){    u.hash=u.hash*27+*p-'a'+1;    u.s.push_back(*p);    ++p;    }    if(*p=='('){        p++; u.l=parse(); p++; u.r=parse(); p++;       }       if(dict.count(u)){        id--; cnt--;        return dict[u];       }       return dict[u]=id;}void print(int v){    if(done[v]==kase) printf("%d",v+1);    else {        done[v]=kase;        printf("%s",nodes[v].s.c_str());        if(nodes[v].l != -1){            printf("(");            print(nodes[v].l);            printf(",");            print(nodes[v].r);            printf(")");        }    }}int T;int main(){    scanf("%d",&T);    for(kase=1;kase<=T;kase++){        dict.clear();        cnt=0;        scanf("%s",s);        p=s;        print(parse());        printf("\n");    }    return 0;}


0 0
原创粉丝点击