详解KMP算法以及python如何实现

作者:MrDoghead 时间:2022-11-17 05:27:18 

算法思路

Knuth-Morris-Pratt(KMP)算法是解决字符串匹配问题的经典算法,下面通过一个例子来演示一下:

给定字符串"BBC ABCDAB ABCDABCDABDE",检查里面是否包含另一个字符串"ABCDABD"。

1.从头开始依次匹配字符,如果不匹配就跳到下一个字符

详解KMP算法以及python如何实现

详解KMP算法以及python如何实现

2.直到发现匹配字符,然后经过一个内循环严查字符串是否匹配

 详解KMP算法以及python如何实现

3.发现最后一个D不匹配,下面就该思考应该把字符串向右移动多少个位置呢?传统做法可能是移动一格,KMP算法就创新在这里。KMP算法通过查询一个Partial Match Table(表内存有字符串信息),然后计算出需要移动的步数,这个表后面会介绍怎么来的。

详解KMP算法以及python如何实现

这里我们看到D前面是B,查表得到第二个B对应的是2,所以 移动数 = 已匹配字符数 - 查表所得数 也就是 6 - 2 = 4, 需要向右移动四格。

详解KMP算法以及python如何实现

下面也是重复这个步骤

详解KMP算法以及python如何实现

直到发现匹配或者字符长度超出(未发现匹配)。

Partial Match Table

那么这个查询的表是怎么来的呢?仍然以"ABCDABD"为例

详解KMP算法以及python如何实现

-"A"的前缀和后缀都为空集,共有元素的长度为0;

-"AB"的前缀为[A],后缀为[B],共有元素的长度为0;

-"ABC"的前缀为[A, AB],后缀为[BC, C],共有元素的长度0;

-"ABCD"的前缀为[A, AB, ABC],后缀为[BCD, CD, D],共有元素的长度为0;

-"ABCDA"的前缀为[A, AB, ABC, ABCD],后缀为[BCDA, CDA, DA, A],共有元素为"A",长度为1;

-"ABCDAB"的前缀为[A, AB, ABC, ABCD, ABCDA],后缀为[BCDAB, CDAB, DAB, AB, B],共有元素为"AB",长度为2;

-"ABCDABD"的前缀为[A, AB, ABC, ABCD, ABCDA, ABCDAB],后缀为[BCDABD, CDABD, DABD, ABD, BD, D],共有元素的长度为0。

python实现


def partial_table(p):
 '''''partial_table("ABCDABD") -> [0, 0, 0, 0, 1, 2, 0]'''
 prefix = set()
 res = [0]
 for i in range(1, len(p)):
   prefix.add(p[:i])
   postfix = {p[j:i + 1] for j in range(1, i + 1)}
   #print(p[:i+1],prefix,postfix,prefix & postfix or {''})
   res.append(len((prefix & postfix or {''}).pop()))
 return res

def kmp_match(s, p):
 m = len(s);
 n = len(p)
 cur = 0 # 起始指针cur
 table = partial_table(p)
 while cur <= m - n:   #只去匹配前m-n个
   for i in range(n):
     if s[i + cur] != p[i]:
       cur += max(i - table[i - 1], 1) # 有了部分匹配表,我们不只是单纯的1位1位往右移,可以一次移动多位
       break
   else:    
     return True # loop从 break 中退出时,else 部分不执行。
 return False

print partial_table1("ABCDABD")
print kmp_match("BBC ABCDAB ABCDABCDABDE", "ABCDABD")

来源:https://www.cnblogs.com/mrdoghead/p/13542400.html

标签:python,KMP,算法
0
投稿

猜你喜欢

  • python数据可视化plt库实例详解

    2022-11-30 21:23:28
  • python人工智能tensorflow函数tf.get_variable使用方法

    2021-09-14 22:52:09
  • js小方框中浏览大图类似google earth效果

    2007-10-28 19:30:00
  • Python 写小游戏吃金币+打乒乓+滑雪(附源码)

    2021-05-17 20:56:37
  • 如何用Python合并lmdb文件

    2023-08-05 17:42:01
  • 教你在SQL Server数据库中导入导出数据

    2008-12-09 14:42:00
  • MySQL的之表结构修改

    2012-01-05 19:16:17
  • 在Python中处理XML的教程

    2021-08-04 17:36:01
  • python3在各种服务器环境中安装配置过程

    2021-10-27 22:49:55
  • Python小程序之在图片上加入数字的代码

    2023-11-14 08:26:48
  • js中鼠标滚轮事件详解

    2010-02-05 12:20:00
  • java实现批量导入Excel表格数据到数据库

    2024-01-19 13:16:58
  • pytorch中index_select()的用法详解

    2022-01-20 19:44:05
  • Python爬虫制作翻译程序的示例代码

    2023-08-13 06:38:35
  • 用python分割TXT文件成4K的TXT文件

    2022-06-27 02:12:44
  • 将SQL 2000日志迁移到SQL Server 2008

    2009-03-25 16:20:00
  • 深入学习Python+Opencv常用四种图像处理操作

    2023-02-22 12:28:27
  • Mysql带And关键字的多条件查询语句

    2024-01-14 08:41:17
  • python3.5绘制随机漫步图

    2022-08-12 14:16:13
  • Python 私有函数的实例详解

    2023-03-07 08:30:40
  • asp之家 网络编程 m.aspxhome.com