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


Posted in Python onSeptember 18, 2020

算法思路

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")

以上就是详解KMP算法以及python如何实现的详细内容,更多关于python实现KMP算法的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
跟老齐学Python之集合的关系
Sep 24 Python
用Python制作检测Linux运行信息的工具的教程
Apr 01 Python
python读取word文档的方法
May 09 Python
Python操作RabbitMQ服务器实现消息队列的路由功能
Jun 29 Python
Python两个内置函数 locals 和globals(学习笔记)
Aug 28 Python
Python实现针对给定单链表删除指定节点的方法
Apr 12 Python
pycharm重置设置,恢复默认设置的方法
Oct 22 Python
python3去掉string中的标点符号方法
Jan 22 Python
使用PYTHON解析Wireshark的PCAP文件方法
Jul 23 Python
python中time、datetime模块的使用
Dec 14 Python
聊聊pytorch测试的时候为何要加上model.eval()
May 23 Python
Django实现翻页的示例代码
May 24 Python
python实现二分查找算法
Sep 18 #Python
Python自定义sorted排序实现方法详解
Sep 18 #Python
python爬虫爬取网页数据并解析数据
Sep 18 #Python
Python实现迪杰斯特拉算法过程解析
Sep 18 #Python
Python 操作 MySQL数据库
Sep 18 #Python
python实现人工蜂群算法
Sep 18 #Python
Python猫眼电影最近上映的电影票房信息
Sep 18 #Python
You might like
多数据表共用一个页的新闻发布
2006/10/09 PHP
PHP中register_globals参数为OFF和ON的区别(register_globals 使用详解)
2012/02/05 PHP
使用php显示搜索引擎来的关键词
2014/02/13 PHP
php不使用插件导出excel的简单方法
2014/03/04 PHP
使用PHP编写发红包程序
2015/07/22 PHP
PHP+JQUERY操作JSON实例
2017/03/23 PHP
PHP实现时间比较和时间差计算的方法示例
2017/07/24 PHP
详解php语言最牛掰的Laravel框架
2017/11/20 PHP
在多个页面使用同一个HTML片段的代码
2011/03/04 Javascript
jQuery中的.bind()、.live()和.delegate()之间区别分析
2011/06/08 Javascript
js中判断Object、Array、Function等引用类型对象是否相等
2012/08/29 Javascript
7款吸引人眼球的jQuery/CSS3特效实例分享
2013/04/25 Javascript
jQuery之ajax删除详解
2014/02/27 Javascript
JQuery拖动表头边框线调整表格列宽效果代码
2014/09/10 Javascript
JS针对Array的各种操作汇总
2016/11/29 Javascript
JavaScript使用ZeroClipboard操作剪切板
2017/05/10 Javascript
利用vue + koa2 + mockjs模拟数据的方法教程
2017/11/22 Javascript
express+mockjs实现模拟后台数据发送功能
2018/01/07 Javascript
使用layui 渲染table数据表格的实例代码
2018/08/19 Javascript
angularJs使用ng-repeat遍历后选中某一个的方法
2018/09/30 Javascript
Vue获取微博授权URL代码实例
2020/11/04 Javascript
[03:40]DOTA2亚洲邀请赛小组赛第二日 赛事回顾
2015/01/31 DOTA
[50:22]完美盛典-2018年度红毯走秀
2018/12/16 DOTA
python实现批量监控网站
2016/09/09 Python
Python中使用haystack实现django全文检索搜索引擎功能
2017/08/26 Python
如何在pycharm中安装第三方包
2020/10/27 Python
放飞蜻蜓反思
2014/02/05 职场文书
党员入党表决心的话
2014/03/11 职场文书
竞选大队干部演讲稿
2014/09/11 职场文书
营销总监岗位职责
2014/09/16 职场文书
员工离职感谢信
2015/01/22 职场文书
高老头读书笔记
2015/06/30 职场文书
自考生自我评价
2019/06/21 职场文书
Python Pandas知识点之缺失值处理详解
2021/05/11 Python
pytorch实现ResNet结构的实例代码
2021/05/17 Python
mysql的Buffer Pool存储及原理
2022/04/02 MySQL