详解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 getopt 参数处理小示例
Jun 09 Python
python中for语句简单遍历数据的方法
May 07 Python
python查看模块,对象的函数方法
Oct 16 Python
python将txt文件读入为np.array的方法
Oct 30 Python
对python mayavi三维绘图的实现详解
Jan 08 Python
python读取目录下所有的jpg文件,并显示第一张图片的示例
Jun 13 Python
python+numpy实现的基本矩阵操作示例
Jul 19 Python
如何使用Python多线程测试并发漏洞
Dec 18 Python
解决Django响应JsonResponse返回json格式数据报错问题
Aug 09 Python
如何用Python 实现全连接神经网络(Multi-layer Perceptron)
Oct 15 Python
python 用opencv实现霍夫线变换
Nov 27 Python
在Ubuntu中安装并配置Pycharm教程的实现方法
Jan 06 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操作Access类(PHP+ODBC+Access)
2007/01/02 PHP
php下清空字符串中的HTML标签的代码
2010/09/06 PHP
php源代码安装常见错误与解决办法分享
2013/05/28 PHP
laravel 验证错误信息到 blade模板的方法
2019/09/29 PHP
javascript脚本编程解决考试分数统计问题
2008/10/18 Javascript
fckeditor 获取文本框值的实现代码
2009/02/09 Javascript
JavaScript中访问节点对象的方法有哪些如何使用
2013/09/24 Javascript
JS判断字符串长度的5个方法(区分中文和英文)
2014/03/18 Javascript
总结JavaScript中布尔操作符||与&amp;&amp;的使用技巧
2015/11/17 Javascript
jQuery遮罩层实现方法实例详解(附遮罩层插件)
2015/12/08 Javascript
详解js跨域原理以及2种解决方案
2015/12/09 Javascript
jQuery使用$.ajax提交表单完整实例
2015/12/11 Javascript
原生js和jquery分别实现横向导航菜单效果
2016/05/13 Javascript
原生js三级联动的简单实现代码
2016/06/07 Javascript
js常用DOM方法详解
2017/02/04 Javascript
JS实现汉字与Unicode码相互转换的方法详解
2017/04/28 Javascript
JS实现为动态创建的元素添加事件操作示例
2018/03/17 Javascript
使用Vue.js和Flask来构建一个单页的App的示例
2018/03/21 Javascript
angular4+百分比进度显示插件用法示例
2019/05/05 Javascript
20个必会的JavaScript面试题(小结)
2019/07/02 Javascript
javascript实现弹幕墙效果
2019/11/28 Javascript
vuejs element table 表格添加行,修改,单独删除行,批量删除行操作
2020/07/18 Javascript
如何用Python合并lmdb文件
2018/07/02 Python
Python按钮的响应事件详解
2019/03/04 Python
详解Python3 pickle模块用法
2019/09/16 Python
python利用dlib获取人脸的68个landmark
2019/11/27 Python
使用python3 实现插入数据到mysql
2020/03/02 Python
Python多线程操作之互斥锁、递归锁、信号量、事件实例详解
2020/03/24 Python
python批量处理多DNS多域名的nslookup解析实现
2020/06/28 Python
美国在线印刷公司:PsPrint
2017/10/12 全球购物
意大利珠宝店:Luxury Zone
2019/01/05 全球购物
Nisbets爱尔兰:英国最大的厨房和餐饮设备供应商
2019/01/26 全球购物
行政办公员自我评价分享
2013/12/14 职场文书
房地产开盘策划方案
2014/02/10 职场文书
导游词之上海杜莎夫人蜡像馆
2019/11/22 职场文书
九大龙王魂骨,山龙王留下躯干骨,榜首死的最憋屈(被捏碎)
2022/03/18 国漫