python3 kmp 字符串匹配的方法


Posted in Python onJuly 07, 2018

先声明,本人菜鸟一个,写博客是为了记录学习的过程,以及自己的理解和心得,可能有的地方写的不好,希望大神指出。。。

抛出问题

给定一个文本串test_str(被匹配的字符串)和模式串pat_str(需要从文本串中匹配的字符串),从文本串test_str中找出模式串pat_str第一次出现的位置,没有的话返回 -1

暴力方式

在说kmp之前,我们先来讲下“暴力方式“,也就是说我们最原始的方法。 

text_str = 'asdabcdace'
pat_str = 'abcdace'

def str_match(text_str,pat_str):
  for i in range(0,len(text_str)):
    j = 1
    while j < len(pat_str):
      if text_str[i:i+j] != pat_str[0:j]: #从text_str第i个字符开始,看匹配是否成功
        break  #匹配失败,直接跳出循环,i+1,继续从第一个字符匹配
      j += 1   #匹配成功就继续匹配下一个字符,知道pat_str每个字符都匹配完
    if j == len(pat_str):
      return i
  return -1

print(str_match(text_str,pat_str))

之所以称之为暴力解法,就是因为每次匹配失败之后就将模式串,向后移动一位,从头开始匹配,一直循环下去。造成时间复杂度高,kmp也就是优化这个地方,每一次匹配失败,下次移动的距离next值

python3 kmp 字符串匹配的方法

KMP

如果让我完全给你讲懂kmp算法可能不太容易,我只能大致粗略的将下它的一步步实现。我认为就一个重点,

如何求出模式串每个字符对应的next值

因为可能,每一次匹配失败的长度的字符不一样,也就对应每次移动的距离不一样,那我们如何求每个字符对应的next值,这就引出了另一个概念

最大前缀和最大后缀

python3 kmp 字符串匹配的方法

假定最大前缀=最大后缀,长度为k 那么第i位字符,对应的next值就为k+1,一次循环就能求出每个字符的next值

代码实现

#求字符串的next值
text_str = 'asdabcdace'
pat_str = 'abcdace'

#得到字符对应的next值
def str_next(s):
  #前两个字符默认等于1
  next = [1,1]
  for x in range(2,len(s)):
    next.append(str_max_prx(s,x,next[x-1]-1) + 1)
  return next
#参数 s字符串,匹配进行到的位置,下次开始匹配的位置
def str_max_prx(s,x,last_value):
  next = 0
  for i in range(last_value,x):
    if s[0:i] == s[x-i:x]:
      next = i
  return next
def str_match(s,m):
  next = str_next(s)
  i=0
  s_len = len(s)
  m_len = len(m)
  while i <= m_len:
    flag = True   #标志位,用来判断是否匹配成功
    index = 1
    while index <= s_len:
      if m[i:i + index] != s[0:index]:
        i = i + next[index]
        flag = False
        break
      else:
        index += 1
    if flag:
      break
  if i >= m_len:
    i = -1
  return i
res = str_match(pat_str,text_str)
print(res)

代码就是这样,很多东西可能还需要自己理解。我记个笔记,为之后方便查找,希望对你能有帮助。也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python实现的十进制小数与二进制小数相互转换功能
Oct 12 Python
Python爬虫抓取代理IP并检验可用性的实例
May 07 Python
python使用pdfminer解析pdf文件的方法示例
Dec 20 Python
对python中Json与object转化的方法详解
Dec 31 Python
解决python文件双击运行秒退的问题
Jun 24 Python
python PIL和CV对 图片的读取,显示,裁剪,保存实现方法
Aug 07 Python
django框架两个使用模板实例
Dec 11 Python
opencv 形态学变换(开运算,闭运算,梯度运算)
Jul 07 Python
Python爬虫过程解析之多线程获取小米应用商店数据
Nov 14 Python
Python 用__new__方法实现单例的操作
Dec 11 Python
Jupyter Notebook 远程访问配置详解
Jan 11 Python
Python命令行参数argv和argparse该如何使用
Feb 08 Python
vue.js实现输入框输入值内容实时响应变化示例
Jul 07 #Python
详解Python最长公共子串和最长公共子序列的实现
Jul 07 #Python
python求最大连续子数组的和
Jul 07 #Python
python 平衡二叉树实现代码示例
Jul 07 #Python
详解python异步编程之asyncio(百万并发)
Jul 07 #Python
基于Python开发chrome插件的方法分析
Jul 07 #Python
Python实现基于C/S架构的聊天室功能详解
Jul 07 #Python
You might like
我见过最全的个人js加解密功能页面
2007/12/12 Javascript
JavaScript入门教程(3) js面向对象
2009/01/31 Javascript
JavaScript flash复制库类 Zero Clipboard
2011/01/17 Javascript
javascript实现文字图片上下滚动的具体实例
2013/06/28 Javascript
JQuery 控制内容长度超出规定长度显示省略号
2014/05/23 Javascript
jQuery实用技巧必备(上)
2015/11/02 Javascript
使用jQuery操作HTML的table表格的实例解析
2016/03/13 Javascript
JS平滑无缝滚动效果的实现代码
2016/05/06 Javascript
谈谈Vue.js——vue-resource全攻略
2017/01/16 Javascript
微信小程序 常用工具类详解及实例
2017/02/15 Javascript
bootstrap警告框示例代码分享
2017/05/17 Javascript
JS获取当前地理位置的方法
2017/10/25 Javascript
js判断文件类型大小并给出提示的实现方法
2018/01/03 Javascript
vue.js与element-ui实现菜单树形结构的解决方法
2018/04/21 Javascript
解决node-sass偶尔安装失败的方法小结
2018/12/05 Javascript
微信小程序防止多次点击跳转(函数节流)
2019/09/19 Javascript
[10:42]Team Liquid Vs Newbee
2018/06/07 DOTA
Python守护进程用法实例分析
2015/06/04 Python
详解python单例模式与metaclass
2016/01/15 Python
使用Python在Windows下获取USB PID&amp;VID的方法
2019/07/02 Python
Python Opencv提取图片中某种颜色组成的图形的方法
2019/09/19 Python
tensorflow estimator 使用hook实现finetune方式
2020/01/21 Python
解决python图像处理图像赋值后变为白色的问题
2020/06/04 Python
Python字符串格式化常用手段及注意事项
2020/06/17 Python
详解使用HTML5 Canvas创建动态粒子网格动画
2016/12/14 HTML / CSS
Groupon荷兰官方网站:高达70%的折扣
2019/11/01 全球购物
通用C#笔试题附答案
2016/11/26 面试题
交通安全演讲稿
2014/01/07 职场文书
元旦联欢会感言
2014/03/04 职场文书
投标诚信承诺书
2014/05/26 职场文书
就业协议书样本
2014/08/20 职场文书
小学班主任经验交流材料
2014/12/16 职场文书
个人党性分析材料
2014/12/19 职场文书
营销计划书范文
2015/01/17 职场文书
2015社区个人工作总结范文
2015/05/13 职场文书
Redis缓存-序列化对象存储乱码问题的解决
2021/06/21 Redis