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中的对象与类型
Dec 11 Python
Python实现脚本锁功能(同时只能执行一个脚本)
May 10 Python
Python学习教程之常用的内置函数大全
Jul 14 Python
PyQt5实现无边框窗口的标题拖动和窗口缩放
Apr 19 Python
浅谈Scrapy网络爬虫框架的工作原理和数据采集
Feb 07 Python
tesserocr与pytesseract模块的使用方法解析
Aug 30 Python
python nmap实现端口扫描器教程
May 28 Python
django连接mysql数据库及建表操作实例详解
Dec 10 Python
Python urlopen()和urlretrieve()用法解析
Jan 07 Python
python实现银行实战系统
Feb 26 Python
经验丰富程序员才知道的8种高级Python技巧
Jul 27 Python
Golang Web 框架Iris安装部署
Aug 14 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/10/09 PHP
Javascript 构造函数 实例分析
2008/11/26 Javascript
JavaScript this调用规则说明
2010/03/08 Javascript
jQuery 表格工具集
2010/04/25 Javascript
用JavaScript玩转游戏物理(一)运动学模拟与粒子系统
2010/06/19 Javascript
AngularJS常见过滤器用法实例总结
2017/07/06 Javascript
10行原生JS实现文字无缝滚动(超简单)
2018/01/02 Javascript
Vue仿今日头条实例详解
2018/02/06 Javascript
老生常谈JS中的继承及实现代码
2018/07/06 Javascript
微信小程序实现签到功能
2018/10/31 Javascript
Vue项目中最新用到的一些实用小技巧
2018/11/06 Javascript
vue实现新闻展示页的步骤详解
2019/04/11 Javascript
跟老齐学Python之有容乃大的list(4)
2014/09/28 Python
Linux下为不同版本python安装第三方库
2016/08/31 Python
PyQt打开保存对话框的方法和使用详解
2019/02/27 Python
Python实现从SQL型数据库读写dataframe型数据的方法【基于pandas】
2019/03/18 Python
numpy数组之存取文件的实现示例
2019/05/24 Python
Python学习笔记之Django创建第一个数据库模型的方法
2019/08/07 Python
Python closure闭包解释及其注意点详解
2019/08/28 Python
python函数修饰符@的使用方法解析
2019/09/02 Python
Python3.7实现验证码登录方式代码实例
2020/02/14 Python
win10下opencv-python特定版本手动安装与pip自动安装教程
2020/03/05 Python
详解使用python3.7配置开发钉钉群自定义机器人(2020年新版攻略)
2020/04/01 Python
tensorflow模型文件(ckpt)转pb文件的方法(不知道输出节点名)
2020/04/22 Python
一款纯css3实现的竖形二级导航的实例教程
2014/12/11 HTML / CSS
Html5新特性用canvas标签画多条直线附效果截图
2014/06/30 HTML / CSS
CK巴西官方网站:Calvin Klein巴西
2019/07/19 全球购物
举例说明类变量和实例变量的区别
2016/06/30 面试题
参观接待方案
2014/03/17 职场文书
记账会计岗位职责
2014/06/16 职场文书
合作协议书格式
2014/08/19 职场文书
电子银行业务授权委托书
2014/10/10 职场文书
幼儿园个人师德总结
2015/02/06 职场文书
小学班主任工作经验交流材料
2015/11/02 职场文书
MySQL基础快速入门知识总结(附思维导图)
2021/09/25 MySQL
css3中2D转换之有趣的transform形变效果
2022/02/24 HTML / CSS