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

本文介绍了一种使用三元组表示节点并结合哈希表进行去重的算法实现。该算法通过C++代码示例展示了如何处理字符串,并利用哈希函数确保唯一性,适用于字符串长度较小的情况。

将每一个结点用一个三元组来表示,然后映射到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;
}


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值