字符串哈希模板
2015-11-05 15:59
176 查看
#include<stdio.h> typedef long long LL; /*【字符串哈希算法】 字符串哈希算法的提出,涉及到如何快速地求两个字符串是否完全相同。 如果是查询多个匹配串与某个模板串的相同性关系,我们可以用KMP实现。 而如果这些匹配串都是某个串的子串呢?从效率上和思维复杂度上讲,都不如用字符串哈希来实现! 什么是字符串哈希呢?比如,我们要哈希一个全为小写字符的串,串长最大为TOP。 1,我们决定取模数Z 2,我们决定字符集哈希数V 3,我们预处理V的幂值:v[0]=1;for(int i=1;i<=TOP;i++)v[i]=v[i-1]*V%Z; 4,我们求出模板串s的哈希值: scanf("%s",s); w=0;for(int i=1;s[i];i++)w=(w*V+s[i]-'a')%Z; 5,我们求出匹配串ss以任一位置为结尾的前缀哈希值: scanf("%s",ss); u[0]=0;for(int i=1;ss[i];i++)u[i]=(u[i-1]*V+ss[i]-'a')%Z; 6,当判定ss[l,r]是否与模板串s相同时,我们求得s[l,r]在同规则下的哈希值ww: 把前缀u[l-1]乘上v[r-(l-1)]的base,用u[r]-u[l-1]*v[r-(l-1)],就得到了纯后缀哈希值,也就是s[l,r]的哈希值。 即ww=(u[r]-u[l-1]*v[r-(l-1)]%Z+Z)%Z. 这时判定w与ww是否相同,就可以判匹配串是否与模板串相同啦。 需要事项1: 如果哈希值不同,那么两个串必定不同。 而就算哈希值相同,两个串依然存在可能性不同。 为了提高稳定性,我们可以取多个pair(取模数Z,字符集哈希数V)。利用两次哈希甚至是多次哈希,提高准确性。 注意事项2: 字符集的不同,我们对应可能采取ch-'a',ch-'A',ch-'0',ch这样各种各样的形式提高哈希的准确的*/ const int TOP=1e5,N=TOP+10; const int Z=1e9+7;//取模数 const int V=26;//字符集哈希数 char s ,ss ; LL v ;//v[x]=V^x%Z LL u ;//u[x]=hashvalue(1,x); LL hashvalue(int l,int r) { return (u[r]-u[l-1]*v[r-(l-1)]%Z+Z)%Z; } int main() { v[0]=1;for(int i=1;i<=TOP;i++)v[i]=v[i-1]*V%Z; scanf("%s",s+1); LL w=0;for(int i=1;s[i];i++)w=(w*V+s[i]-'a')%Z; scanf("%s",ss+1); u[0]=0;for(int i=1;ss[i];i++)u[i]=(u[i-1]*V+ss[i]-'a')%Z; while(1) { int l,r;scanf("%d%d",&l,&r); LL ww=hashvalue(l,r); printf("ss[%d,%d]%ss\n",l,r,ww==w?"==":"!="); } return 0; }
相关文章推荐
- 动易2006序列号破解算法公布
- Ruby实现的矩阵连乘算法
- C#插入法排序算法实例分析
- 超大数据量存储常用数据库分表分库算法总结
- C#数据结构与算法揭秘二
- C#冒泡法排序算法实例分析
- 算法练习之从String.indexOf的模拟实现开始
- C#算法之关于大牛生小牛的问题
- C#实现的算24点游戏算法实例分析
- c语言实现的带通配符匹配算法
- 浅析STL中的常用算法
- 算法之排列算法与组合算法详解
- C++实现一维向量旋转算法
- Ruby实现的合并排序算法
- C#折半插入排序算法实现方法
- 基于C++实现的各种内部排序算法汇总
- C++线性时间的排序算法分析
- C++实现汉诺塔算法经典实例
- PHP实现克鲁斯卡尔算法实例解析
- C#获取关键字附近文字算法实例