字符串hash补充(模数情况下)

字符串模板,在模数意义下的,比较好用

 1 #include<stdio.h>
 2 typedef long long LL;
 3 /*【字符串哈希算法】
 4 字符串哈希算法的提出,涉及到如何快速地求两个字符串是否完全相同。
 5 如果是查询多个匹配串与某个模板串的相同性关系,我们可以用KMP实现。
 6 而如果这些匹配串都是某个串的子串呢?从效率上和思维复杂度上讲,都不如用字符串哈希来实现!
 7 什么是字符串哈希呢?比如,我们要哈希一个全为小写字符的串,串长最大为TOP。
 8 1,我们决定取模数Z
 9 2,我们决定字符集哈希数V
10 3,我们预处理V的幂值:v[0]=1;for(int i=1;i<=TOP;i++)v[i]=v[i-1]*V%Z;
11 4,我们求出模板串s的哈希值:
12 scanf("%s",s);
13 w=0;for(int i=1;s[i];i++)w=(w*V+s[i]-'a')%Z;
14 5,我们求出匹配串ss以任一位置为结尾的前缀哈希值:
15 scanf("%s",ss);
16 u[0]=0;for(int i=1;ss[i];i++)u[i]=(u[i-1]*V+ss[i]-'a')%Z;
17 6,当判定ss[l,r]是否与模板串s相同时,我们求得s[l,r]在同规则下的哈希值ww:
18 把前缀u[l-1]乘上v[r-(l-1)]的base,用u[r]-u[l-1]*v[r-(l-1)],就得到了纯后缀哈希值,也就是s[l,r]的哈希值。
19 即ww=(u[r]-u[l-1]*v[r-(l-1)]%Z+Z)%Z.
20 这时判定w与ww是否相同,就可以判匹配串是否与模板串相同啦。
21 需要事项1:
22 如果哈希值不同,那么两个串必定不同。
23 而就算哈希值相同,两个串依然存在可能性不同。
24 为了提高稳定性,我们可以取多个pair(取模数Z,字符集哈希数V)。利用两次哈希甚至是多次哈希,提高准确性。
25 注意事项2:
26 字符集的不同,我们对应可能采取ch-'a',ch-'A',ch-'0',ch这样各种各样的形式提高哈希的准确的*/
27  
28 const int TOP=1e5,N=TOP+10;
29 const int Z=1e9+7;//取模数
30 const int V=26;//字符集哈希数
31 char s[N],ss[N];
32 LL v[N];/[x]=V^x%Z
33 LL u[N];//u[x]=hashvalue(1,x);
34 LL hashvalue(int l,int r)
35 {
36     return (u[r]-u[l-1]*v[r-(l-1)]%Z+Z)%Z;
37 }
38 int main()
39 {
40     v[0]=1;for(int i=1;i<=TOP;i++)v[i]=v[i-1]*V%Z;
41     scanf("%s",s+1);
42     LL w=0;for(int i=1;s[i];i++)w=(w*V+s[i]-'a')%Z;
43     scanf("%s",ss+1);
44     u[0]=0;for(int i=1;ss[i];i++)u[i]=(u[i-1]*V+ss[i]-'a')%Z;
45     while(1)
46     {
47         int l,r;scanf("%d%d",&l,&r);
48         LL ww=hashvalue(l,r);
49         printf("ss[%d,%d]%ss\n",l,r,ww==w?"==":"!=");
50     }
51     return 0;
52 }

 

posted @ 2018-06-10 19:16  romaLzhih  阅读(204)  评论(0编辑  收藏  举报