Python:Rabin-Karp 算法哈希

2023-11-24

我为了好玩而实现 Rabin-Karp 算法。我遇到了这个伪代码:

    RABIN -KARP -MATCHER (T, P, d, q)
    1 n = T.length
    2 m = P.length
    3 h = d^(m-1) mod q
    4 p=0
    5 t= 0
    6 for i = 1 to m
    / preprocessing
    /
    7 p = (dp + P [i]) mod q
    8 t = (dt + T [i]) mod q
    9 for s = 0 to n-m
    / matching
    /
    10     if p == t
    11         if P [1... m] == T [s + 1...s + m]
    12             print “Pattern occurs with shift” s
    13     if s < n-m
    14         t  = (d(t-T[s + 1]h) + T [s + m + 1]) mod q

我在 Python 2.7 中实现如下:

def Rabin_Karp_Matcher(text, pattern, d, q):
    n = len(text)
    m = len(pattern)
    h = pow(d,m-1)%q
    p = 0
    t =0
    result = []
    for i in range(m): # preprocessing
        p = (d*p+ord(pattern[i]))%q
        t = (d*t+ord(text[i]))%q
    for s in range(n-m):
        if p == t: # check character by character
            match = True
            for i in range(m):
                if pattern[i] != text[s+i]:
                    match = False
                    break
            if match:
                result = result + [s]
        if s < n-m:
                t = (d*(t-ord(text[s+1])*h)+ord(text[s+m]))%q #index out of bounds here
    return result

其中结果是包含模式文本中的索引的列表。

我的代码无法在 3141592653589793 中找到 26 我怀疑这与伪代码第 14 行定义的哈希码有关。任何人都可以帮忙解决这个问题吗?

我传入了以下参数:

P =“26” T =“3141592653589793” d = 257 q = 11

P 和 T 必须是字符串/字符数组


这是您的代码的工作版本:

def Rabin_Karp_Matcher(text, pattern, d, q):
    n = len(text)
    m = len(pattern)
    h = pow(d,m-1)%q
    p = 0
    t = 0
    result = []
    for i in range(m): # preprocessing
        p = (d*p+ord(pattern[i]))%q
        t = (d*t+ord(text[i]))%q
    for s in range(n-m+1): # note the +1
        if p == t: # check character by character
            match = True
            for i in range(m):
                if pattern[i] != text[s+i]:
                    match = False
                    break
            if match:
                result = result + [s]
        if s < n-m:
            t = (t-h*ord(text[s]))%q # remove letter s
            t = (t*d+ord(text[s+m]))%q # add letter s+m
            t = (t+q)%q # make sure that t >= 0
    return result
print (Rabin_Karp_Matcher ("3141592653589793", "26", 257, 11))
print (Rabin_Karp_Matcher ("xxxxx", "xx", 40999999, 999999937))

输出是:

[6]
[0, 1, 2, 3]

第一步,检查是否text[0..m] == pattern。在第二步中,您要检查是否text[1..m+1] == pattern。因此你删除了text[0]来自散列(目前它乘以您预先计算的h): t = (t-h*ord(text[s]))%q。然后,添加text[m] to it: t = (t*d+ord(text[s+m]))%q。在下一步中,您将删除text[1]并添加text[m+1], 等等。这t = (t+q)%q线在那里是因为负数模q产生范围内的余数(-q; 0],我们希望它在范围内[0; q).

请注意,您要检查总共n-m+1子串,不是n-m,因此正确的循环是for s in range(n-m+1)。通过第二个示例检查(在“xxxxx”中查找“xx”)。

另外值得注意的是:

  1. 线路h = pow(d,m-1)%q可能会太慢,如果m很大。最好对结果取模q在每个之后m-2乘法。或者直接使用内置的方式:h = pow(d,m-1,q),正如@oBrstisf8o 在评论中所建议的。

  2. 该算法在最坏情况下仍然是O(nm)。和text="a"*100000 and pattern="a"*50000,它会找到 50001 个文本子字符串与模式匹配的位置,并且会逐个字符地检查它们。如果您希望代码在这种极端情况下能够快速运行,则应该跳过逐个字符的比较,并找到一种处理误报的方法(即哈希值相等但字符串不相等)。选择一个大素数q可能有助于将误报的可能性降低到可接受的水平。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python:Rabin-Karp 算法哈希 的相关文章

  • 从 C 中的 char* 获取单个字符

    有没有办法在 C 中逐字符遍历或从 char 中提取单个字符 考虑以下代码 现在获得单个角色的最佳方式是什么 建议我一种不使用任何字符串函数的方法 char a STRING 其他方式 char i for i a i i i points
  • 计算温度的偏导数(温度的水平平流)

    我想知道哪种方法计算x和y方向温度的偏导数 温度的水平平流 最正确 第二个代码使用温度 纬向风和经向风的数据矩阵 提取温度 T 纬向风分量 u 和经向风分量 v 的数据 import matplotlib pyplot as plt imp
  • 在 python + Flask + Gunicorn + nginx + Compute Engine 应用程序中从 Google Cloud Storage 读取文件失败

    在 python Flask Gunicorn nginx Compute Engine 应用程序中读取从 Google Cloud Storage 下载的文件失败 代码链接 https github com samuq CE test h
  • Python 可以使用单独的媒体播放器打开 mp3 文件吗? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 是否可以开一个mp3Python 中的文件 可以使用Popen 我并不是要在程序中运行它 我的意思是作为媒体播放器中的一个单独窗口或其
  • 如何更改条形图上的 y 轴限制?

    我有一个df 我从中索引了europe n我绘制了一个条形图 europe n r 5 c 45 looks like this df Country string df Population numeric 变量 plt bar df C
  • 绘图:仅保留最相关的数据

    为了节省带宽并且不用自己生成图片 图表 我计划使用 Google 的图表 API http code google com apis chart http code google com apis chart 它的工作原理是简单地发出一个
  • 肥皂服务的良好框架是什么?

    我正在寻找一个用于肥皂的好框架service 我更喜欢使用Pythonic框架 但是在查看了soaplib rpclib 太不稳定 SOAPy 不适用于2 7 和ZSI 太 令人困惑 之后 我不确定这是否可能 我对使用另一种语言感到满意 尽
  • Python MySQL 模块

    我正在开发一个需要与 MySQL 数据库交互的 Web 应用程序 但我似乎找不到任何真正适合 Python 的模块 我特别寻找快速模块 能够处理数十万个连接 和查询 所有这些都在短时间内完成 而不会对速度产生重大影响 我想我的答案将是游戏领
  • 更改Python pylab玫瑰/极坐标图中图例标题的字体大小

    我正在尝试更改玫瑰图或 极地 图上现有图例标题的字体大小 大部分代码是由不在的其他人编写的 我已经添加 ax legend title legend title setp l get title fontsize 8 添加标题 legend
  • 如何最好地将包含列表或元组的 Pandas 列提取到多个列中[重复]

    这个问题在这里已经有答案了 我不小心用错误重复的链接关闭了这个问题 这是正确的 Pandas 将列表的列拆分为多列 https stackoverflow com questions 35491274 pandas split column
  • Python变量赋值问题

    a b 0 1 while b lt 50 print b a b b a b 输出 1 2 4 8 16 32 wheras a b 0 1 while b lt 50 print b a b b a b 输出 正确的斐波那契数列 1 1
  • 不重复的Python组合

    我有一个数字列表 我想从中进行组合 如果我有清单 t 2 2 2 2 4 c list itertools combinations t 4 结果是 2 2 2 2 2 2 2 4 2 2 2 4 2 2 2 4 2 2 2 4 但我想得到
  • 收到的标签值 1 超出了 [0, 1) 的有效范围 - Python、Keras

    我正在使用具有张量流背景的 keras 开发一个简单的 cnn 分类器 def cnnKeras training data training labels test data test labels n dim print Initiat
  • 避免在列表理解中计算相同的表达式两次[重复]

    这个问题在这里已经有答案了 我在列表理解中使用一个函数和一个 if 函数 new list f x for x in old list if f x 0 令我恼火的是这个表达f x 在每个循环中计算两次 有没有办法以更清洁的方式做到这一点
  • Beautiful Soup 获取动态表数据

    我有以下代码 url https www basketball reference com leagues NBA 2017 standings html all expanded standings html urlopen url so
  • Python 类方法的示例用例是什么?

    我读了Python 中的类方法有什么用 https stackoverflow com questions 38238 what are class methods in python for但那篇文章中的例子很复杂 我正在寻找 Pytho
  • 检测图像是否损坏或损坏

    我需要以编程方式检查用户在我的应用程序上选择作为壁纸的图像是否已损坏或损坏 基本上我为用户提供了选择自己的图像作为壁纸的选项 现在 当图像加载时 我只想检查它是否已损坏 如果您正在寻找 PHP 解决方案而不是 javascript 解决方案
  • 安排 Asyncio 任务每 X 秒执行一次?

    我正在尝试创建一个 python 不和谐机器人 它将每隔 X 秒检查一次活跃会员 并根据会员的在线时间奖励积分 我正在使用 asyncio 来处理聊天命令 这一切都正常 我的问题是找到一种方法来安排每隔 X 秒异步检查一次活动成员 我已经阅
  • 在 python 中使用递归替代 len()

    作为 CS1301 问题的一部分 我正在尝试使用递归编写一个函数 该函数将执行与 len 完全相同的操作 但是 我有两个问题 我正在使用全局变量 但我在课程中还没有学到这一点 cs1301 自动评分器告诉我 我的函数返回 26 而不是 13
  • 用于桌面数据库应用程序的 Python 框架

    是否有一个框架可以为Python开发桌面数据库应用程序 一些带有CRUD屏幕的屏幕 我正在寻找类似于 Windows 窗体的东西 能够将 TextField Combos 和其他 UI 隐喻与datasets连接到关系数据库例如 MySQL

随机推荐