Hash

本文介绍了一种通过手写Hash方法解决Map数据结构中常数过大的问题。利用131作为基数将字符串转换为数值,并使用前缀和思想维护Hash数组,以高效地计算字符串任意部分的Hash值。

为了解决map常数大的问题,有的时候要用到手写\(Hash\)

把字符串看成是一个\(base\)进制的数,一般\(base\)取131就会比较稳妥
那么对于一个字符串\(S=c_1c_2c_3...c_n\)的哈希值就是\(c_1*base^n+c_2*base^{n-1}+c_3*base^{n-2}+...+c_n*base^1\)
直接用\(unsigned long long\)保存自然溢出也不会产生哈希冲突

有的时候要截取一个字符串的一部分单独进行比较,这时候就可以用前缀和思想维护一个\(Hash\)数组
\(H[i]\)表示把字符串的前\(i\) 项看成一个\(base\)进制的数的值,那么转移的时候\(H[i]=H[i-1]*base+s[i]\)
所以这时候\(l\)\(r\)\(Hash\)值就是\(H[r]-H[l-1]*base^{r-l+1}\) 至于\(base\)的次方大小只要在求\(H\)的时候顺便求出即可

void hash(int *a,char *c)
{
    int ss=strlen(c);
    p[0]=1;
    for(i=0;i<=c;i++)
    {
        a[i+1]=a[i]*base+c[i-'a'];
        p[i+1]=p[i]*base;
    }
}

转载于:https://www.cnblogs.com/ZUTTER/p/9615310.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值