字符串匹配(hash算法)
转载
hash函数对大家来说不陌生吧 ?
而这次我们就用hash函数来实现字符串匹配。
首先我们会想一下二进制数。
对于任意一个二进制数,我们将它化为10进制的数的方法如下(以二进制数1101101为例):
hash用的也是一样的原理,为每一个前缀(也可以后缀,笔者习惯1 base,所以喜欢用前缀来计算,Hash[i] = Hash[i - 1] * x + si。
一般地,
而对于l - r区间的hash值,则为:
但是如果n很大呢?那样不是会溢出了吗?
因此我们把hash值储存在unsigned long long里面, 那样溢出时,会自动取余2的64次方,but这样可能会使2个不同串的哈希值相同,但这样的概率极低(不排除你的运气不好)。
因此我们可以通过Hash值来比较两个字符串是否相等。
给出多项式hash的处理:
typedef unsigned long long ull; const int N = 100000 + 5; const ull base = 163; char s[N]; ull hash[N]; void init(){//处理hash值 p[0] = 1; hash[0] = 0; int n = strlen(s + 1); for(int i = 1; i <=100000; i ++)p[i] =p[i-1] * base; for(int i = 1; i <= n; i ++)hash[i] = hash[i - 1] * base + (s[i] - 'a'); } ull get(int l, int r, ull g[]){//取出g里l - r里面的字符串的hash值 return g[r] - g[l - 1] * p[r - l + 1]; }