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的*args和**kwargs用法
Nov 01 Python
python中使用序列的方法
Aug 03 Python
Python基于pygame实现的弹力球效果(附源码)
Nov 11 Python
Python数组定义方法
Apr 13 Python
python队列queue模块详解
Apr 27 Python
利用Python实现Shp格式向GeoJSON的转换方法
Jul 09 Python
python与C、C++混编的四种方式(小结)
Jul 15 Python
python Django框架实现web端分页呈现数据
Oct 31 Python
Python Sympy计算梯度、散度和旋度的实例
Dec 06 Python
pyecharts调整图例与各板块的位置间距实例
May 16 Python
详解python定时简单爬取网页新闻存入数据库并发送邮件
Nov 27 Python
python3.7.2 tkinter entry框限定输入数字的操作
May 22 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中实现Javascript的escape()函数代码
2010/08/08 PHP
Yii框架调试心得--在页面输出执行sql语句
2014/12/25 PHP
PHP下载远程文件到本地存储的方法
2015/03/24 PHP
PHP读书笔记整理_结构语句详解
2016/07/01 PHP
JavaScript使用prototype定义对象类型
2007/02/07 Javascript
jQuery 学习入门篇附实例代码
2010/03/16 Javascript
JS无限树状列表实现代码
2011/01/11 Javascript
Jquery post传递数组方法实现思路及代码
2013/04/28 Javascript
javascript将相对路径转绝对路径示例
2014/03/14 Javascript
JavaScript利用正则表达式去除日期中的“-”
2014/07/01 Javascript
vue2.X组件学习心得(新手必看篇)
2017/07/05 Javascript
基于bootstrop常用类总结(推荐)
2017/09/11 Javascript
Bootstrap 树控件使用经验分享(图文解说)
2017/11/06 Javascript
Vue的移动端多图上传插件vue-easy-uploader的示例代码
2017/11/27 Javascript
Promise扫盲贴
2019/06/24 Javascript
layui框架与SSM前后台交互的方法
2019/09/12 Javascript
记一次python 内存泄漏问题及解决过程
2018/11/29 Python
python按照多个条件排序的方法
2019/02/08 Python
django项目登录中使用图片验证码的实现方法
2019/08/15 Python
python SVD压缩图像的实现代码
2019/11/05 Python
python topk()函数求最大和最小值实例
2020/04/02 Python
Python自动发送和收取邮件的方法
2020/08/12 Python
python3.8动态人脸识别的实现示例
2020/09/21 Python
ffmpeg+Python实现B站MP4格式音频与视频的合并示例代码
2020/10/21 Python
Django contrib auth authenticate函数源码解析
2020/11/12 Python
css3编写浏览器背景渐变背景色的方法
2018/03/05 HTML / CSS
俄罗斯名牌服装网上商店:UNIQUE FABRIC
2019/07/25 全球购物
偷看我的初中毕业鉴定
2014/01/29 职场文书
小学教师听课制度
2014/02/01 职场文书
毕业寄语大全
2014/04/09 职场文书
四风问题个人自查剖析材料思想汇报
2014/09/21 职场文书
廉洁自律个人总结
2015/02/14 职场文书
测量员岗位职责
2015/02/14 职场文书
因公司原因离职的辞职信范文
2015/05/12 职场文书
校园之声广播稿
2015/08/18 职场文书
SpringBoot系列之MongoDB Aggregations用法详解
2022/02/12 MongoDB