字符串哈希 学习笔记

目录

  • Part 1:什么是字符串哈希
  • Part 2:字符串哈希(RK)算法的实现
  • Part 3:练习

Part 1:什么是字符串哈希

所谓的字符串哈希,就是每个字符串都有一个 hash 值(如果字符串 st完全相等,那么它们的 hash 值也相等)。可以通过许多方法来求出字符串的 hash 值。

但是,许多方法求出的 hash 值可能不是很有效,即不同的字符串的 hash 值相等。因此,如果两个字符串的 hash 值不相同,则它们肯定不相同;如果它们的 hash 值相同,它们也不一定相同

Part 2:字符串哈希(RK)算法的实现

RK 算法的思路:将模式串 phash 值跟主串 s 中的每一个长度为 |p| 的子串的 hash 值比较。如果不同,则它们肯定不相等;如果相同,则再逐位比较。

设模式串为 p,长度为 m;主串为 s,长度为 n。则模式串 p 可以看作是一个 m 位的 d 进制数 A,主串 s 可以看作是一个 n 位的 d 进制数。我们的模式匹配过程就是将 A 与主串中的每个长度为 md 进制数 S[t…t+m−1](t=0,1,2,…,n−m+1) 的值做比较,所以整个模式匹配过程就变成了两个 d 进制数之间的比较过程。例如模式串为 123,主串为 65127451234,就是将十进制数 123 跟十进制数 651,512,127,274,745,451,512,123 的逐个比较过程。

首先需要求解 A。根据上文可得:

A=Pm−1+d×(Pm−2+d×(Pm−3+⋯+d×(P1+d×P0)…))

我们可以发现,hash 值是可以递推转移的。因此,可以得出以下公式:

hash⁡(t+1)=d×(hash⁡(t)−dm−1×hash⁡(t))+hash⁡(t+m)

代码实现:

 
 
 
 
 
 
 
 
pair<int,int> hash_value(char s[],int len){
  int u=0,v=0;
  for(int i=0;i<len;++i){
    u=(u*bas+s[i])%p1;
    v=(v*bas+s[i])%p2;
  }
  return make_pair(u,v);
}//u和v分别代表这个字符串的两个hash值,这样更不容易出错
//注意数据范围,实际上int有点小
 

Part 3:练习

posted @ 2022-03-12 10:15  xiaomuyun  阅读(242)  评论(0编辑  收藏  举报