字符串哈希/字符串前缀哈希法

概述

字符串哈希全称字符串前缀哈希法,把字符串映射为一个P进制数,实现不同的字符串映射不同的数字

注意

字符不能映射为0,不然会导致冲突,例如A,AA都为0

P取131或13331的冲突概率低

计算结果可能会溢出,需要取模,用2^64,这样用unsigned long long存储,溢出的结果就是取模的结果

例子

以十进制为例,P=10,假设字符只包含1~9且权值为1 ~ 9

维护字符串的哈希值:对于字符串“123”,h[1]=1,h[2]=12,h[3]=123,即用前面的哈希值乘以进制加上当前权值

判断字符串是否相同:假设给定字符串a="59123"和字符串b=“123”,问a中的"123"和b中的"123"是否为同一个字符串。通过维护两个字符串的哈希值得到a字符串的h[5]=59123,b字符串的h[3]=123,现在要把a中"123"的哈希值取出来,如果用"123"之前"59"的哈希值乘以一定的值,使其与59123的位数一样,就可以用59123减去,求出123。乘以多少呢?看相差的位数,是所求字符串的长度,如"59"和"59123"相差的位数是3,即"123"的长度,因此是p[3]=1000,59123-59*1000=123,同样求出b中“123”的哈希值,两者相等,字符串相同

代码

typedef unsigned long long ull;
ull h[N],p[N];//h[i]为前i个字符的哈希值,p[i]为P^i
//初始化
p[0]=1;
for(int i=1;i<=n;++i)
{
    h[i]=h[i-1]*P+s[i];
    p[i]=p[i-1]*P;
}
//获取s[l~r]的哈希值
ull get(int l,int r)
{
    return h[r]-h[l-1]*p[r-l+1];
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值