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中chr、unichr、ord字符函数之间的对比
Jun 16 Python
python中的格式化输出用法总结
Jul 28 Python
Django使用httpresponse返回用户头像实例代码
Jan 26 Python
ubuntu安装sublime3并配置python3环境的方法
Mar 15 Python
python实现QQ空间自动点赞功能
Apr 09 Python
对Python _取log的几种方式小结
Jul 25 Python
python字符串替换re.sub()方法解析
Sep 18 Python
Python搭建代理IP池实现获取IP的方法
Oct 27 Python
Django继承自带user表并重写的例子
Nov 18 Python
Python的pygame安装教程详解
Feb 10 Python
PyCharm 无法 import pandas 程序卡住的解决方式
Mar 09 Python
OpenCV图片漫画效果的实现示例
Aug 18 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操作Access类(PHP+ODBC+Access)
2007/01/02 PHP
php中数组首字符过滤功能代码
2012/07/31 PHP
PHP fopen 读取带中文URL地址的一点见解
2012/09/25 PHP
php安装swoole扩展的方法
2015/03/19 PHP
php数值转换时间及时间转换数值用法示例
2017/05/18 PHP
详解PHP5.6.30与Apache2.4.x配置
2017/06/02 PHP
PHP实现找出链表中环的入口节点
2018/01/16 PHP
javascript 动态添加表格行
2006/06/22 Javascript
jQuery 使用手册(四)
2009/09/23 Javascript
js变换显示图片的实例
2013/04/16 Javascript
关于js遍历表格的实例
2013/07/10 Javascript
jQuery焦点图切换特效插件封装实例
2013/08/18 Javascript
javascript中处理时间戳为日期格式的方法
2014/01/02 Javascript
javascript实现鼠标放上后下边对应内容变换的效果
2015/08/06 Javascript
微信小程序之发送短信倒计时功能
2017/08/30 Javascript
浅谈react性能优化的方法
2018/09/05 Javascript
Swiper实现导航栏滚动效果
2020/10/16 Javascript
[04:16]DOTA2全国高校联赛16强抽签
2018/05/02 DOTA
在Python中使用HTMLParser解析HTML的教程
2015/04/29 Python
简单了解django orm中介模型
2019/07/30 Python
解决echarts中饼图标签重叠的问题
2020/05/16 Python
python中rb含义理解
2020/06/18 Python
python类共享变量操作
2020/09/03 Python
CSS3 实现童年的纸飞机
2019/05/05 HTML / CSS
Ramy Brook官网:美国现代女装品牌
2019/06/18 全球购物
澳大利亚办公室装修:JasonL Office Furniture
2019/06/25 全球购物
欧洲最大的高尔夫零售商:American Golf
2019/09/02 全球购物
工程管理造价应届生求职信
2013/11/13 职场文书
大学生标准推荐信范文
2013/11/25 职场文书
党员2014两会学习心得体会
2014/03/17 职场文书
教师学习三严三实心得体会
2014/10/13 职场文书
市委召开党的群众路线教育实践活动总结大会报告
2014/10/21 职场文书
2016年全国爱牙日宣传活动总结
2016/04/05 职场文书
2021年pycharm的最新安装教程及基本使用图文详解
2021/04/03 Python
sql通过日期判断年龄函数的示例代码
2021/07/16 SQL Server
十大动画制作软件,Adobe产品上榜两款,第一是行业标准软件
2022/03/18 杂记