详解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 相关文章推荐
CentOS安装pillow报错的解决方法
Jan 27 Python
实例解析Python的Twisted框架中Deferred对象的用法
May 25 Python
PYTHON压平嵌套列表的简单实现
Jun 08 Python
Python socket网络编程TCP/IP服务器与客户端通信
Jan 05 Python
Python实现获取前100组勾股数的方法示例
May 04 Python
pip install urllib2不能安装的解决方法
Jun 12 Python
python保存文件方法小结
Jul 27 Python
Python从数据库读取大量数据批量写入文件的方法
Dec 10 Python
django将网络中的图片,保存成model中的ImageField的实例
Aug 07 Python
django model 条件过滤 queryset.filter(**condtions)用法详解
May 20 Python
Python并发请求下限制QPS(每秒查询率)的实现代码
Jun 05 Python
Python爬虫获取op.gg英雄联盟英雄对位胜率的源码
Jan 29 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中可能用来加密字符串的函数[base64_encode、urlencode、sha1]
2012/01/16 PHP
destoon之一键登录设置
2014/06/21 PHP
PHP使用递归生成文章树
2015/04/21 PHP
PHP实现适用于文件内容操作的分页类
2016/06/15 PHP
jQuery+php简单实现全选删除的方法
2016/11/28 PHP
PHP实现的猴王算法(猴子选大王)示例
2018/04/30 PHP
php使用QueryList轻松采集js动态渲染页面方法
2018/09/11 PHP
javascript 动态设置已知select的option的value值的代码
2009/12/16 Javascript
JQuery datepicker 使用方法
2011/05/20 Javascript
JavaScript修改css样式style动态改变元素样式
2013/12/16 Javascript
node.js中的fs.read方法使用说明
2014/12/17 Javascript
JavaScript中常用的六种互动方法示例
2015/03/13 Javascript
比较常见的javascript中定义函数的区别
2015/11/09 Javascript
javascript制作照片墙及制作过程中出现的问题
2016/04/04 Javascript
H5移动端适配 Flexible方案
2016/10/24 Javascript
js获取ip和地区
2017/03/10 Javascript
Vue中点击active并第一个默认选中功能的实现
2020/02/24 Javascript
快速了解python leveldb
2018/01/18 Python
Python 类的特殊成员解析
2018/06/20 Python
Python实现的统计文章单词次数功能示例
2019/07/08 Python
python列表删除和多重循环退出原理详解
2020/03/26 Python
Python+Dlib+Opencv实现人脸采集并表情判别功能的代码
2020/07/01 Python
如何使用Python调整图像大小
2020/09/26 Python
python3实现语音转文字(语音识别)和文字转语音(语音合成)
2020/10/14 Python
一款利用纯css3实现的win8加载动画的实例分析
2014/12/11 HTML / CSS
html5跨域通讯之postMessage的用法总结
2013/11/07 HTML / CSS
Currentbody西班牙:美容仪专家
2019/09/28 全球购物
瑞士隐形眼镜和护理产品网上商店:Linsenklick
2019/10/21 全球购物
linux面试题参考答案(1)
2016/01/22 面试题
如何利用XMLHTTP检测URL及探测服务器信息
2013/11/10 面试题
宿舍违规用电检讨书
2014/02/16 职场文书
学雷锋演讲稿
2014/03/04 职场文书
遗嘱公证书标准样本
2014/04/08 职场文书
关于安全的演讲稿
2014/05/09 职场文书
2015年学校党支部工作总结
2015/04/01 职场文书
Nginx使用Lua模块实现WAF的原理解析
2021/09/04 Servers