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 zip文件 压缩
Dec 24 Python
Python使用稀疏矩阵节省内存实例
Jun 27 Python
修复CentOS7升级Python到3.6版本后yum不能正确使用的解决方法
Jan 26 Python
python快速建立超简单的web服务器的实现方法
Feb 17 Python
解决pandas使用read_csv()读取文件遇到的问题
Jun 15 Python
Python基于多线程实现ping扫描功能示例
Jul 23 Python
tensorflow 中对数组元素的操作方法
Jul 27 Python
python+opencv实现霍夫变换检测直线
Oct 23 Python
Pycharm 2019 破解激活方法图文详解
Oct 11 Python
python logging 重复写日志问题解决办法详解
Aug 04 Python
Django修改app名称和数据表迁移方案实现
Sep 17 Python
Python实现照片卡通化
Dec 06 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
PHP防注入安全代码
2008/04/09 PHP
Php Image Resize图片大小调整的函数代码
2011/01/17 PHP
PHP图片上传代码
2013/11/04 PHP
PHP实现抽奖功能实例代码
2020/06/30 PHP
JS跨域总结
2012/08/30 Javascript
Javascript 中 null、NaN和undefined的区别总结
2013/04/10 Javascript
JavaScript实现的GBK、UTF8字符串实际长度计算函数
2014/08/27 Javascript
跟我学习javascript的函数调用和构造函数调用
2015/11/16 Javascript
js动态添加的DIV中的onclick事件简单实例
2016/07/25 Javascript
JS实现动态增加和删除li标签行的实例代码
2016/10/16 Javascript
jQuery简单自定义图片轮播插件及用法示例
2016/11/21 Javascript
浅谈regExp的test方法取得的值变化的原因及处理方法
2017/03/01 Javascript
javascript html5轻松实现拖动功能
2017/03/01 Javascript
基于JavaScript实现类名的添加与移除
2017/04/23 Javascript
vue 挂载路由到头部导航的方法
2017/11/13 Javascript
Javasript设计模式之链式调用详解
2018/04/26 Javascript
Nodejs让异步变成同步的方法
2019/03/02 NodeJs
微信小程序用户拒绝授权的处理方法详解
2019/09/20 Javascript
关于vue组件事件属性穿透详解
2019/10/28 Javascript
vue组件暴露和.js文件暴露接口操作
2020/08/11 Javascript
原生JavaScript实现贪吃蛇游戏
2020/11/04 Javascript
[46:32]Fnatic vs OG 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
简介Python的collections模块中defaultdict类型的用法
2016/07/07 Python
Python中模块string.py详解
2017/03/12 Python
Python函数参数匹配模型通用规则keyword-only参数详解
2019/06/10 Python
opencv3/C++实现视频读取、视频写入
2019/12/11 Python
基于Python绘制美观动态圆环图、饼图
2020/06/03 Python
Python 基于jwt实现认证机制流程解析
2020/06/22 Python
Python RabbitMQ实现简单的进程间通信示例
2020/07/02 Python
Python ConfigParser模块的使用示例
2020/10/12 Python
使用css实现android系统的loading加载动画
2019/07/25 HTML / CSS
运动会广播稿150字
2014/02/19 职场文书
单位法定代表人授权委托书
2014/09/20 职场文书
2016年会领导致辞稿
2015/07/29 职场文书
Python进行区间取值案例讲解
2021/08/02 Python
Vue OpenLayer测距功能的实现
2022/04/20 Vue.js