字符串从入门到入土第二讲(Hash)

牛客字符串班笔记

Hash 定义

定义

Hash 是一种单射函数,可以将万物单向映射成一个整数值。

字符串 Hash 是指将一个字符串串映射成一个整数值,用于快速比较字符串是否相等。

H(S):S的 Hash值,即映射后的整数值。

性质

必要性:若 S = T,一定有 H(S) = H(T)

非充分性:若 H(S) = H(T),不一定有 S = T

Hash 检测

Hash 检测:通过 H(S) 和 H(T) 是否相等,来判断 S 和 T 是否相等的方法。

Hash 冲突:H(S) = H(T) ,但是 S ≠ T,即为发生 Hash 冲突。

Hash 检测时发生 Hash 冲突的概率是衡量 Hash 算法好坏的重要指标

设计 Hash 算法

多项式 Hash

将字符串看作是某个进制(Base)下的字符串。

H ( S ) = ∑ i = 1 i ≤ ∣ s ∣ = n S [ i ] ∗ B a s e 1 + n − i H(S)=\sum_{i=1}^{i \leq |s|=n} S[i]*Base^{1+n-i} H(S)=i=1is=nS[i]Base1+ni

            = H ( S [ 1 , ∣ S ∣ − 1 ] ) ∗ B a s e + S [ ∣ S ∣ ] ~~~~~~~~~~~=H(S[1,|S|-1])*Base+S[|S|]            =H(S[1,S1])Base+S[S]

            = S [ 1 ] ∗ B a s e n + S [ 2 ] ∗ B a s e n − 1 + . . . + S [ n ] ∗ B a s e 0 ~~~~~~~~~~~=S[1]*Base^n+S[2]*Base^{n-1}+...+S[n]*Base^0            =S[1]Basen+S[2]Basen1+...+S[n]Base0

栗子:
字符集 ∑ = a , b , , . . . , o \sum = {a,b,,...,o} =a,b,,...,o分别对应十六进制的 1 2 … F
若 S = adenoo,则 H ( S ) = 145 E F ( 16 ) = 133503 9 ( 10 ) H(S) = 145EF_{(16)}=1335039_{(10)} H(S)=145EF(16)=1335039(10)

优点:字符串和 Hash 值一一对应,无 Hash 冲突

缺点:数据范围过大,难以存储和比较

多项式取模 Hash(模哈)

模哈是为了解决多项式 Hash 的缺点,在效率和冲突率之间进行的折中:

将多项式 Hash 的值对一个较大的质数取模。

H‘(S) = H(S) % Mod

优点:多项式 Hash 可以存储。

缺点:小概率发生 Hash 冲突。

模哈冲突概率

模哈冲突:H(S) ≠ H(T) 但 H(S) % Mod = H(T) % Mod

H(S) 被随机映射成 [1, Mod-1] 内的整数。

生日悖论

有 n 个人,他们的生日是 [1,365] 中的随机整数

n > 365 n > 365 n>365,一定有两个人生日相同

n ≤ 365 n \leq 365 n365,没有人生日相同的概率为 A ( 365 , n ) 36 5 n \frac{A(365,n)}{365^n} 365nA(365,n)

当 n = 23 时,上述结果约为 0.46,即有超过 50% 的概率有人生日相同。

即当检验次数超过 M o d \sqrt{Mod} Mod ,就会有较大概率发生错误。

因此,在模哈中使用的 Mod 最好超过 Hash 检验次数的平方、

Hash 的三种姿势

Hash 模数

优秀的 Hash 模数应该 满足:足够大

自然溢出:ULL保存 Hash 值,利用硬件特性,使 Hash 值自然溢出,即 M o d = 2 64 Mod = 2^{64} Mod=264,但容易造成 Hash 冲突 。

优秀的 Hash 模数还应该是质数

当模数是合数,相当于选了很多小模数,Hash 冲突的概率为 n k p 1 ∗ p 2 ∗ . . . ∗ p k \frac{n^k}{p_1*p_2*...*p_k} p1p2...pknk,否则为 n p \frac{n}{p} pn

单模

选取 1 0 9 10^9 109 1 0 1 0 10^10 1010范围的大质数作为 Hash 模数。但也有广为人知的方法构造冲突。

双模

进行多次不同质数的单模 Hash,降低冲突率。

在不泄露模数的前提,没有已知方法可以构造冲突。

子串 Hash

H ( s [ l , r ] ) = ( S [ l ] ∗ B a s e r − l + S [ l + 1 ] ∗ B a s e r − l − 1 + . . . + S [ r ] ) H(s[l,r])=(S[l]*Base^{r-l}+S[l+1]*Base^{r-l-1}+...+S[r]) H(s[l,r])=(S[l]Baserl+S[l+1]Baserl1+...+S[r])%Mod

F ( i ) = H ( p r e [ i ] ) F(i) = H(pre[i]) F(i)=H(pre[i])

F ( l − 1 ) = ( S [ 1 ] ∗ B a s e l − 2 + S [ 2 ] ∗ B a s e l − 3 + . . . + S [ l − 1 ] ) F(l-1)=(S[1]*Base^{l-2}+S[2]*Base^{l-3}+...+S[l-1]) F(l1)=(S[1]Basel2+S[2]Basel3+...+S[l1])% Mod

       F ( r ) = ( S [ 1 ] ∗ B a s e r − 1 + S [ 2 ] ∗ B a s e r − 2 + . . . + S [ r ] ) ~~~~~~F(r)=(S[1]*Base^{r-1}+S[2]*Base^{r-2}+...+S[r])       F(r)=(S[1]Baser1+S[2]Baser2+...+S[r])% Mod

H ( s [ l , r ] ) = F ( r ) − F ( l − 1 ) ∗ B a s e r − l + 1 H(s[l,r])=F(r)-F(l-1)*Base^{r-l+1} H(s[l,r])=F(r)F(l1)Baserl+1

题单

大质数表

from https://www.cnblogs.com/ljxtt/p/13514346.html

IQBFPAHTO310YUO7A8X.png

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值