详解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实现人人网登录示例分享
Jan 19 Python
举例讲解Django中数据模型访问外键值的方法
Jul 21 Python
python模块之re正则表达式详解
Feb 03 Python
python操作MySQL 模拟简单银行转账操作
Sep 27 Python
Python中面向对象你应该知道的一下知识
Jul 10 Python
Python3 列表,数组,矩阵的相互转换的方法示例
Aug 05 Python
详解Python修复遥感影像条带的两种方式
Feb 23 Python
python 函数嵌套及多函数共同运行知识点讲解
Mar 03 Python
python虚拟环境模块venv使用及示例
Mar 04 Python
python deque模块简单使用代码实例
Mar 12 Python
Pandas的数据过滤实现
Jan 15 Python
Django实现简单的分页功能
Feb 22 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
DISCUZ 分页代码
2007/01/02 PHP
php 全文搜索和替换的实现代码
2008/07/29 PHP
php实现统计网站在线人数的方法
2015/05/12 PHP
php正则替换处理HTML页面的方法
2015/06/17 PHP
PHP中异常处理的一些方法整理
2015/07/03 PHP
PHP开发中csrf攻击的简单演示和防范
2017/05/07 PHP
PHP注释语法规范与命名规范详解篇
2018/01/21 PHP
jQuery学习5 jQuery事件模型
2010/02/07 Javascript
手机号码,密码正则验证
2014/09/04 Javascript
jQuery使用fadein方法实现渐出效果实例
2015/03/27 Javascript
Cookies 和 Session的详解及区别
2017/04/21 Javascript
node.js中使用Export和Import的方法
2017/09/18 Javascript
webpack vue 项目打包生成的文件,资源文件报404问题的修复方法(总结篇)
2018/01/09 Javascript
JS脚本加载后执行相应回调函数的操作方法
2018/02/28 Javascript
关于vue v-for循环解决img标签的src动态绑定问题
2018/09/18 Javascript
layui复选框的全选与取消实现方法
2019/09/02 Javascript
JS中比Switch...Case更优雅的多条件判断写法
2019/09/05 Javascript
微信小程序聊天功能的示例代码
2020/01/13 Javascript
浅谈vue 多个变量同时赋相同值互相影响
2020/08/05 Javascript
JavaScript Blob对象原理及用法详解
2020/10/14 Javascript
[40:03]Liquid vs Optic 2018国际邀请赛淘汰赛BO3 第一场 8.21
2018/08/22 DOTA
Windows下Eclipse+PyDev配置Python+PyQt4开发环境
2016/05/17 Python
Python实现提取XML内容并保存到Excel中的方法
2018/09/01 Python
Python之使用adb shell命令启动应用的方法详解
2019/01/07 Python
详解matplotlib中pyplot和面向对象两种绘图模式之间的关系
2021/01/22 Python
Python将QQ聊天记录生成词云的示例代码
2021/02/10 Python
html5中的input新属性range使用记录
2014/09/05 HTML / CSS
巧用HTML5给按钮背景设计不同的动画简单实例
2016/08/09 HTML / CSS
美国领先的户外服装与装备用品店:Moosejaw
2016/08/25 全球购物
埃弗顿足球俱乐部官方网上商店:Everton Direct
2018/01/13 全球购物
优秀村官事迹材料
2014/01/10 职场文书
成语的广告词
2014/03/19 职场文书
竞选学生会主席演讲稿
2014/04/24 职场文书
幼儿教师求职信
2014/05/24 职场文书
《秋天的怀念》教学反思
2016/02/17 职场文书
Windows11性能真的上涨35%? 桌面酷睿i9实测结果公开
2021/11/21 数码科技