字符串hash的一种实现

字符串hash是指将一个字符串s映射为一个,使得该整数可以尽可能唯一的代表也就是唯一标识。换言之,如果两个字符的hash值相同那么我们可以认为两者相同。

这里使用的hash策略,便是把一个字符串的每一位赋予权值
假设都是大写的英文字母。
我们设

H[i]ihash

那么
H[i]=H[i1]p+val[i]

这里因为是大写英文字母,只有26 中不同的表示,所以这里可以设p为26。(实际上就是把26进制数用10进制数表示)
接下的问题是如果字符串的位数很长,那么很可能所产生的hash值会超过技术表示的范围(以int和long类型为例)。
所以我们可以设置一个数mod,即去余
H[i]=(H[i1]p+val[i]%mod

那么这样可以解决数字太大的问题,但是会造成的另一个问题是产生碰撞,即不同的字符串的hash值可能会相同。
根据相关资料,如果我们把 p 设置为一个10710000019大小,把 mod 设为一个 109(1000000009) 大小的数,那么发生碰撞的概率就非常低。
后来我问斌爷,斌爷说把p设为233就够啦,基本上碰撞的概率极小233。

一个延伸问题:如果我得到了一个字符串的hash值,那么怎么得到其中任意一个子串的hash?
首先易知:

H[i...j]=val[i]pji+val[i+1]pji1+val[i+2]pji2+...+val[j]p0

显然:
H[j]=H[i1]pji+1+H[i...j]

所以:
H[i...j]=(H[j]H[i1]pji+1)

这个时候去模:
H[i...j]=((H[j]H[i1]pji+1)%mod+mod)%mod

完毕。

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值