详解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中列表生成式的用法
Mar 31 Python
Python使用logging结合decorator模式实现优化日志输出的方法
Apr 16 Python
python中闭包Closure函数作为返回值的方法示例
Dec 17 Python
Python3基础教程之递归函数简单示例
Jun 07 Python
python操作excel让工作自动化
Aug 09 Python
Python django搭建layui提交表单,表格,图标的实例
Nov 18 Python
Python 使用 prettytable 库打印表格美化输出功能
Dec 26 Python
Python如何获取Win7,Win10系统缩放大小
Jan 10 Python
Python递归及尾递归优化操作实例分析
Feb 01 Python
python实现无边框进度条的实例代码
Dec 30 Python
python爬虫智能翻页批量下载文件的实例详解
Feb 02 Python
Python虚拟环境virtualenv是如何使用的
Jun 20 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
PHP表单验证的3个函数ISSET()、empty()、is_numeric()的使用方法
2011/08/22 PHP
解析array splice的移除数组中指定键的值,返回一个新的数组
2013/07/02 PHP
PHP查找数值数组中不重复最大和最小的10个数的方法
2015/04/20 PHP
php获取开始与结束日期之间所有日期的方法
2016/11/29 PHP
php使用redis的几种常见操作方式和用法示例
2020/02/20 PHP
基于jquery的一个拖拽到指定区域内的效果
2011/09/21 Javascript
jquery中$.post()方法的简单实例
2014/02/04 Javascript
浅谈js中的闭包
2015/03/16 Javascript
JavaScript基本数据类型及值类型和引用类型
2015/08/25 Javascript
JavaScript添加随滚动条滚动窗体的方法
2016/02/23 Javascript
jquery利用json实现页面之间传值的实例解析
2016/12/12 Javascript
javascript 初学教程及五子棋小程序的简单实现
2017/07/04 Javascript
微信小程序之页面拦截器的示例代码
2017/09/07 Javascript
js通过Date对象实现倒计时动画效果
2017/10/27 Javascript
JS使用贪心算法解决找零问题示例
2017/11/27 Javascript
手写简单的jQuery雪花飘落效果实例
2018/04/22 jQuery
微信小程序实现无限滚动列表
2020/05/29 Javascript
微信小程序实现星级评价效果
2018/12/28 Javascript
javascript实现时钟动画
2020/12/03 Javascript
Python3.X 线程中信号量的使用方法示例
2017/07/24 Python
python如何实现内容写在图片上
2018/03/23 Python
OPENCV去除小连通区域,去除孔洞的实例讲解
2018/06/21 Python
Python定时任务APScheduler的实例实例详解
2019/07/22 Python
python实现DEM数据的阴影生成的方法
2019/07/23 Python
python机器学习实现决策树
2019/11/11 Python
python列表推导式操作解析
2019/11/26 Python
Flask和pyecharts实现动态数据可视化
2020/02/26 Python
keras做CNN的训练误差loss的下降操作
2020/06/22 Python
纯CSS3绘制打火机动画火焰效果
2016/07/18 HTML / CSS
日本著名化妆品零售网站:Cosme Land
2019/03/01 全球购物
学校办公室主任职责
2013/12/27 职场文书
酒店总经理欢迎词
2014/01/15 职场文书
幽默自我介绍演讲稿
2014/08/21 职场文书
2015暑期社会实践个人总结
2015/07/13 职场文书
Python语言规范之Pylint的详细用法
2021/06/24 Python
Nginx性能优化之Gzip压缩设置详解(最大程度提高页面打开速度)
2022/02/12 Servers