📅  最后修改于: 2023-12-03 15:06:50.704000             🧑  作者: Mango
Rabin-Karp 算法是一种字符串匹配算法,用来在一个主字符串中查找一个子字符串的出现位置。该算法的时间复杂度为 $O(n)$,与 KMP 算法($O(n+m)$)相比,更适合处理长文本串的匹配问题。
Rabin-Karp 算法的主要思想是使用哈希函数将字符串转换为一个数字,然后在此数值上进行比较。该算法的哈希函数可以使用多种方式实现,例如把字符当作数字来看待,然后再对它们进行某种运算,如乘法、求模等等。
Rabin-Karp 算法可以用于计算一个字符串中的不同子串数量。下面给出 Python 代码实现。
def calc_distinct_substrings(s: str) -> int:
n = len(s)
res = set()
# 初始化值
base = 26
mod = 10 ** 9 + 7
h = pow(base, n-1) % mod
p_hash = 0
for c in s:
p_hash = (p_hash * base + ord(c)) % mod
# 遍历字符串
for i in range(n):
res.add(p_hash)
# 滚动更新哈希值
if i < n-1:
p_hash = (p_hash * base - ord(s[i]) * h + ord(s[i+1])) % mod
h = h // base
return len(res)
该函数输入一个字符串 s
,返回不同子串的数量。它首先初始化哈希函数所需的一些值:
base
:哈希函数的底数;mod
:哈希函数的模数,我们采用 $10^9 + 7$,因为它是一个质数,可以保证哈希值的唯一性;h
:理论上字符串首位的贡献权重,我们采用 $base^{n-1}$。然后计算初始哈希值 p_hash
,遍历字符串 s
,在更新哈希值时,先删除第一位的贡献(即乘上 $base^{n-1}$ 再取模),再添加下一位的贡献(即乘上 base
再加上下一位的 ASCII 值再取模)。
最后,把每次计算出来的哈希值加入集合 res
中,最后返回集合中的元素数量,即为不同子串的数量。