Rabin Karp - Rabin-Karp算法


问题

在文本中查找模式出现的所有位置(长度为长度为都是正整数且)。

解法

从位置开始的匹配,每次成功的匹配都需要时间复杂度为的遍历,才能确定是否成立。如果用来表示字符串的哈希值,表示字符串的哈希值,则比较是否成功的时间复杂度为。显然当时必然有。反之若哈希值相同,再用简单匹配来确定字符串确实为真,这样即可找出所有成功匹配。

我们通过Rabin Fingerprint算法计算字符串的哈希值,ASCII码中每个字符对应的数字值范围在之间,设每读入新的字符时旧的哈希值的扩大倍数为(这个是字符表大小的范围)。则有:

实际我们想计算的是,当右移一位时,不仅要考虑右边界新加入的字符,还需要考虑左边界离开的字符。一个字符从最右边界一直移动到最左边界,其值乘以次。因此哈希值要减去。特别注意长度为

由于数字太大时计算会溢出,用一个较大的素数来对结果取模,最终得到哈希函数:

Rabin Fingerprint算法可以连续的处理字符串,在时间复杂度为内求出所有字符串的哈希值(其中)。Rabin-Karp算法的时间复杂度为,其中是模式在文本中出现的次数。


Rabin-Karp

Rabin Fingerprint


源码

RabinKarp.h

RabinKarp.cpp

测试

RabinKarpTest.cpp