UVa 12219 Common Subexpression Elimination (stl,模拟,实现)

一般来说,把一颗子树离散成一个int,把一个结点的字符离散成一个int会方便处理

直接map离散。当然一个结点最多只有4个小写字母,也可以直接编码成一个27进制的整数,舍掉0,为了区分0和0000。

需要注意的是有可能只有一个结点。

 

#include<bits/stdc++.h>
using namespace std;

const int maxlen = 5e5;
const int maxn = 5e4+1;
char str[maxlen];

map<string,int> smp;
map<string,int>::iterator sit;
vector<string> scache;
#define PB push_back
struct Node
{
    int l,r;
    int sid;
    int Hash;
    bool operator < (const Node& x) const{
        return sid<x.sid || (sid==x.sid && (l < x.l || (l == x.l && r < x.r) ));
    }
}tr[maxn];

map<Node,int> mp;
map<Node,int>::iterator it;
#define se second
#define fi first
#define MP make_pair

int id_cnt;

int SID(string &s)
{
    if((sit = smp.find(s)) != smp.end()) return sit->se;
    scache.PB(s);
    smp.insert(MP(s,scache.size()));
    return scache.size();
}

int ID(Node &nd)
{
    if((it = mp.find(nd)) != mp.end()) return it->se;
    mp.insert(MP(nd,id_cnt));
    tr[id_cnt] = nd;
    return id_cnt++;
}



int build(int x,int &len)
{
    Node u; u.Hash = 0;
    string s;
    int i;
    for(i = x; str[i]; i++){
        if(str[i] == ',' || str[i] == ')'){
            s.assign(str+x,str+i);
            u.sid = SID(s);
            len = s.size();
            u.l = u.r = -1;
            return ID(u);
        }else if(str[i] == '('){
            s.assign(str+x,str+i);
            u.sid = SID(s);
            int lsz, rsz;
            u.l = build(++i,lsz);
            i += lsz;
            u.r = build(++i,rsz);
            len = s.size()+lsz+rsz+3;
            return ID(u);
        }
    }
    s.assign(str+x,str+i);//只有一个结点
    u.sid = SID(s);
    u.l = u.r = -1;
    return ID(u);
}

int dfs_clock;

void dfs(int u)
{
    if(!tr[u].Hash){
        tr[u].Hash = ++dfs_clock;
        printf("%s",scache[tr[u].sid-1].c_str());
    }else {
        printf("%d",tr[u].Hash); return;
    }
    if(~tr[u].l){
        putchar('(');
        dfs(tr[u].l);
        putchar(',');
        dfs(tr[u].r);
        putchar(')');
    }
}


int main()
{
    //freopen("in.txt","r",stdin);
    int T; scanf("%d\n",&T);
    while(T--){
        gets(str);
        mp.clear(); id_cnt = 0;
        scache.clear(); smp.clear();
        int len;
        int root = build(0,len);
        dfs_clock = 0;
        dfs(root);putchar('\n');
    }
    return 0;
}

 

posted @ 2015-08-25 14:25  陈瑞宇  阅读(358)  评论(0编辑  收藏  举报