Rabin Karp 算法

Rabin Karp 算法

Rabin Karp 算法,简称 RK 算法,是由 Michael Oser Rabin 和 Richard Manning Karp 在1987 年提出的字符串搜索算法。该算法主要用于在文本中搜索单个模式串的位置,其基于哈希函数的原理,将字符串和模式都映射为一个整数值,并通过比较这些整数值来确定它们是否匹配。

基本思想

哈希函数的使用:Rabin Karp 算法将字符串和模式都视为数字(例如,将它们看作字符编码的值),然后使用哈希函数来计算它们的哈希值。
滚动哈希算法:在 RK 算法中,一个重要的步骤是滚动哈希算法,它允许我们快速计算文本串中每个子串的哈希值,而不需要重新计算整个子串的哈希值。这大大提高了算法的效率。
算法步骤

  1. 预处理: 计算模式串 p 的哈希值 hash_p。 计算文本串 T 中每个长度为 m(模式串长度)的子串的哈希值,并将它们与hash_p 进行比较。
  2. 匹配过程: 对于文本串 T 中的每个子串,如果其哈希值与 hash_p相等,则进一步检查子串和模式串是否完全匹配(以避免哈希冲突)。 如果哈希值不同,则直接跳过该子串,继续向后匹配。如果找到匹配的子串,则返回其起始位置。 如果遍历完整个文本串仍未找到匹配项,则返回 -1。

滚动哈希算法

在 Rabin-Karp(RK)算法中,滚动哈希(Rolling Hash)是一个重要的概念,用于高效地计算字符串的哈希值,特别是在处理字符串的子串匹配问题时。滚动哈希允许我们在 O(1) 时间复杂度内将哈希值从一个子串更新到其相邻的子串,这使得 RK 算法在处理文本搜索时非常高效。
下面我们用一个例子来解释一下这种算法思想。
在这里插入图片描述

PYTHON代码实现说明

def rabinKarp(T: str, p: str, d: int, q: int) -> int:
    n, m = len(T), len(p)
    if n < m:
        return -1  # 如果文本串长度小于模式串长度,直接返回-1
    hash_p, hash_t = 0, 0
    for i in range(m):
        # 计算模式串 p 的哈希值,假设d为256
        hash_p = (hash_p * d + ord(p[i])) % q  #这里就是实现几次方,345就是3*256的二次方+4*256加5*256的0次方
        # 计算文本串 T 中第一个子串的哈希值      其中ord()代表将值变成ASCII值
        hash_t = (hash_t * d + ord(T[i])) % q  #当hash_t hash_p过大时,q会生效,q一般是比较大,防止数值溢出
    power = pow(d, m - 1, q)  # 使用模幂运算,避免大数溢出  d 的 m-1 次方对 q 取模的结果
    for i in range(n - m + 1):    #这里是n-m+1 是因为如果文本字符串长度为5, 搜索的字符串长度为3,那就是有5-3+1=3种可能
        if hash_p == hash_t:  # 检查哈希值是否相等  
            # 如果哈希值相等,验证模式串和子串每个字符是否完全相同  
            if T[i:i + m] == p:  # 使用切片比较,避免额外的循环
                print( i )       #识别正确,打印位置值
                # 计算下一个相邻子串的哈希值
        if i < n - m:
            # 移除字符 T[i] 的哈希值贡献,这里滚动哈希
            hash_t = (hash_t - power * ord(T[i])) % q
            # 如果 hash_t 为负,则加上 q 使其非负  
            if hash_t < 0:
                hash_t += q
                # 增加字符 T[i + m] 的哈希值贡献
            hash_t = (hash_t * d + ord(T[i + m])) % q
            
 print(rabinKarp("abddsadabdjehwqqiabdoliqweoabd","abd",25,10011))    //进行验证
0
7
17
27  

总结

Rabin-Karp 算法在文本搜索、生物信息学(如 DNA 序列比对)、网络安全(如病毒检测)等领域有广泛应用。它特别适用于在大型文本数据集中快速查找模式串的场景。其次Rabin-Karp 算法是一种高效的字符串搜索算法,它通过哈希技术加速了搜索过程。该算法在大多数情况下表现良好,但需要注意处理哈希冲突和选择合适的哈希函数及参数。在适当的应用场景下,Rabin-Karp 算法可以显著提高字符串搜索的效率。

参考资料

LeetCode 算法笔记(LeetCode-Notes)

自律每一天,fighting

  • 15
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值