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实现的tab文件操作类分享
Nov 20 Python
Python AES加密模块用法分析
May 22 Python
Python模拟随机游走图形效果示例
Feb 06 Python
单链表反转python实现代码示例
Feb 08 Python
Python实现基于KNN算法的笔迹识别功能详解
Jul 09 Python
Python中GeoJson和bokeh-1的使用讲解
Jan 03 Python
python print输出延时,让其立刻输出的方法
Jan 07 Python
python引用(import)某个模块提示没找到对应模块的解决方法
Jan 19 Python
python实现复制大量文件功能
Aug 31 Python
python时间日期操作方法实例小结
Feb 06 Python
Python3内置函数chr和ord实现进制转换
Jun 05 Python
python如何使用代码运行助手
Jul 03 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生成自己的LOG文件
2006/10/09 PHP
php 无限分类的树类代码
2009/12/03 PHP
ThinkPHP模板引擎之导入资源文件方法详解
2014/06/18 PHP
php PDO实现的事务回滚示例
2017/03/23 PHP
Laravel框架定时任务2种实现方式示例
2018/12/08 PHP
Laravel5.4框架使用socialite实现github登录的方法
2019/03/20 PHP
js继承 Base类的源码解析
2008/12/30 Javascript
原生JavaScript实现连连看游戏(附源码)
2013/11/05 Javascript
多选列表框动态添加,移动,删除,全选等操作的简单实例
2014/01/13 Javascript
JavaScript通过prototype给对象定义属性用法实例
2015/03/23 Javascript
你所不了解的javascript操作DOM的细节知识点(一)
2015/06/17 Javascript
一步步教大家编写酷炫的导航栏js+css实现
2016/03/14 Javascript
基于javascript实现九宫格大转盘效果
2020/05/28 Javascript
编写React组件项目实践分析
2018/03/04 Javascript
vue.js移动数组位置,同时更新视图的方法
2018/03/08 Javascript
浅谈node.js 命令行工具(cli)
2018/05/10 Javascript
Vue2.x中利用@font-size引入字体图标报错的解决方法
2018/09/28 Javascript
vue.js+elementUI实现点击左右箭头切换头像功能(类似轮播图效果)
2019/09/05 Javascript
JS扁平化输出数组的2种方法解析
2019/09/17 Javascript
Vue+Vuex实现自动登录的知识点详解
2020/03/04 Javascript
JavaScript实现留言板案例
2020/03/17 Javascript
vue 使用async写数字动态加载效果案例
2020/07/18 Javascript
elementUI同一页面展示多个Dialog的实现
2020/11/19 Javascript
[02:28]DOTA2 2015国际邀请赛中国区预选赛首日现场百态
2015/05/26 DOTA
python中定义结构体的方法
2013/03/04 Python
python入门之语句(if语句、while语句、for语句)
2015/01/19 Python
Python外星人入侵游戏编程完整版
2020/03/30 Python
期末考试动员演讲稿
2014/01/10 职场文书
公司同意接收函
2014/01/13 职场文书
开学典礼感言
2014/02/16 职场文书
安全生产管理合理化建议书
2014/03/12 职场文书
焦点访谈观后感
2015/06/11 职场文书
高温慰问简报
2015/07/21 职场文书
导游词之贵州织金洞
2019/10/12 职场文书
golang 语言中错误处理机制
2021/08/30 Golang
KVM基础命令详解
2022/04/30 Servers