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创建xml的方法
Mar 10 Python
Python快速从注释生成文档的方法
Dec 26 Python
非递归的输出1-N的全排列实例(推荐)
Apr 11 Python
Python拼接字符串的7种方法总结
Nov 01 Python
对python xlrd读取datetime类型数据的方法详解
Dec 26 Python
Python关于excel和shp的使用在matplotlib
Jan 03 Python
python将控制台输出保存至文件的方法
Jan 07 Python
Django框架实现分页显示内容的方法详解
May 10 Python
python提取照片坐标信息的实例代码
Aug 14 Python
Python使用多进程运行含有任意个参数的函数
May 02 Python
Python自带的IDE在哪里
Jul 01 Python
Python性能分析工具py-spy原理用法解析
Jul 27 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编程中八种常见的文件操作方式
2006/11/19 PHP
php验证码实现代码(3种)
2015/09/07 PHP
详解在PHP的Yii框架中使用行为Behaviors的方法
2016/03/18 PHP
js切换div css注意的细节
2012/12/10 Javascript
Ext JS添加子组件的误区探讨
2013/06/28 Javascript
Js中的onblur和onfocus事件应用介绍
2013/08/27 Javascript
JavaScript加强之自定义callback示例
2013/09/21 Javascript
JavaScript将数组转换成CSV格式的方法
2015/03/19 Javascript
JavaScript中switch语句的用法详解
2015/06/03 Javascript
JQuery控制图片由中心点逐渐放大效果
2016/06/26 Javascript
关于javascript的一些知识以及循环详解
2016/09/12 Javascript
jquery封装插件时匿名函数形参和实参的写法解释
2017/02/14 Javascript
Vue + Webpack + Vue-loader学习教程之功能介绍篇
2017/03/14 Javascript
Bootstrap Table列宽拖动的方法
2018/08/15 Javascript
vue 登录滑动验证实现代码
2018/08/24 Javascript
[03:35]2018年度DOTA2最佳辅助位选手5号位-完美盛典
2018/12/17 DOTA
对于Python编程中一些重用与缩减的建议
2015/04/14 Python
Python实现模拟登录及表单提交的方法
2015/07/25 Python
Python_LDA实现方法详解
2017/10/25 Python
在windows下Python打印彩色字体的方法
2018/05/15 Python
Python 字符串处理特殊空格\xc2\xa0\t\n Non-breaking space
2020/02/23 Python
查看keras各种网络结构各层的名字方式
2020/06/11 Python
Selenium Webdriver元素定位的八种常用方式(小结)
2021/01/13 Python
Javascript 高级手势使用介绍
2013/04/21 HTML / CSS
Notino瑞典:购买香水和美容产品
2019/07/26 全球购物
泰国在线书店:SE-ED
2020/06/21 全球购物
TCP协议通讯的过程和步骤是什么
2015/10/18 面试题
会计专业毕业生自我评价
2013/09/25 职场文书
售房协议书
2014/08/19 职场文书
赔偿协议书
2015/01/27 职场文书
街道社区活动报告
2015/02/05 职场文书
就业证明函
2015/06/17 职场文书
运输公司工作总结
2015/08/11 职场文书
大学班长竞选稿
2015/11/20 职场文书
建立共青团委员会的请示
2019/04/02 职场文书
Win2008系统搭建DHCP服务器
2022/06/25 Servers