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自动化测试实例解析
Sep 28 Python
Django1.7+python 2.78+pycharm配置mysql数据库教程
Nov 18 Python
浅谈MySQL中的触发器
May 05 Python
python实现类的静态变量用法实例
May 08 Python
django创建自定义模板处理器的实例详解
Aug 14 Python
pandas 两列时间相减换算为秒的方法
Apr 20 Python
python消除序列的重复值并保持顺序不变的实例
Nov 08 Python
python读取几个G的csv文件方法
Jan 07 Python
python实现的分析并统计nginx日志数据功能示例
Dec 21 Python
python中字符串的编码与解码详析
Dec 03 Python
python 使用openpyxl读取excel数据
Feb 18 Python
Matlab求解数组中的最大值及它所在的具体位置
Apr 16 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
用户的详细注册和判断
2006/10/09 PHP
Mysql中分页查询的两个解决方法比较
2013/05/02 PHP
通过dbi使用perl连接mysql数据库的方法
2014/04/16 PHP
PHP识别二维码的方法(php-zbarcode安装与使用)
2016/07/07 PHP
php 5.4 全新的代码复用Trait详解
2017/01/05 PHP
点击文章内容处弹出页面代码
2009/10/01 Javascript
JavaScript将相对地址转换为绝对地址示例代码
2013/07/19 Javascript
实现动画效果核心方式的js代码
2013/09/27 Javascript
微信内置浏览器私有接口WeixinJSBridge介绍
2015/05/25 Javascript
谈谈我对JavaScript DOM事件的理解
2015/12/18 Javascript
JS 日期与时间戮相互转化的简单实例
2016/06/22 Javascript
JS获取中文拼音首字母并通过拼音首字母快速查找页面内对应中文内容的方法【附demo源码】
2016/08/19 Javascript
微信小程序 Video API实例详解
2016/10/02 Javascript
jQuery上传多张图片带进度条样式(DEMO)
2017/03/02 Javascript
js放到head中失效的原因与解决方法
2017/03/07 Javascript
vue1.0和vue2.0的watch监听事件写法详解
2018/09/11 Javascript
微信小程序导航栏滑动定位功能示例(实现CSS3的positionsticky效果)
2019/01/24 Javascript
Vue项目中使用better-scroll实现菜单映射功能方法
2019/09/11 Javascript
Python赋值语句后逗号的作用分析
2015/06/08 Python
Python多进程机制实例详解
2015/07/02 Python
Python 多线程的实例详解
2017/09/07 Python
Python pymongo模块用法示例
2018/03/31 Python
python3+PyQt5+Qt Designer实现扩展对话框
2018/04/20 Python
目前最全的python的就业方向
2018/06/05 Python
新手入门Python编程的8个实用建议
2019/07/12 Python
Python实现自动装机功能案例分析
2020/10/22 Python
经典C++面试题一
2016/11/06 面试题
自荐书模板
2013/12/19 职场文书
毕业生的自我评价
2013/12/30 职场文书
回门宴答谢词
2014/01/13 职场文书
高一化学教学反思
2014/02/05 职场文书
人力资源求职信
2014/05/25 职场文书
工业设计专业自荐书
2014/06/05 职场文书
雨中的树观后感
2015/06/03 职场文书
幼儿园六一儿童节主持词
2015/06/30 职场文书
PostgreSQL解析URL的方法
2021/08/02 PostgreSQL