导语

本篇内容研究字符串匹配问题,首先介绍字符串匹配问题,引出Brute-Force算法及其优化方法,最后深入详解KMP算法。文章结构如下(全文阅读需要30分钟左右):

字符串匹配问题

1字符串匹配问题是什么

"字符串A是否为字符串B的子串?如果是的话出现在B的哪些位置?"该问题就是字符串匹配问题,字符串A称为模式串,字符串B称为主串

2应用

字符串匹配应用很广泛,比如你想在一篇文章中找到某个关键字所在的位置,或者是你想在一份名单中找到某个名字是否出现等等

Brute-Force算法

1算法核心思想

Brute-Force算法简称BF算法(并不是Boy Friend),算法的核心思想跟名字一样粗暴,如下所示:

2python代码实现

假设n为主串长度,m为模式串长度。每一轮字符串比较:最差的情况为模式串最后一个字与主串不同其他都相同(如模式串为AAB,主串对应部分为AAC),必须走完整个字符串才能得出结果,因此复杂度为O(m)。所有轮字符串比较:最差的情况是移动到最后一次比较才寻找得到,总共需要n-m+1次,主串通常比模式串长很多,故Brute-Force时间复杂度为O(nm)

3算法优化思路

最坏的情况:

两个字符串是否相同的比较很难优化,只能逐字比较。然而比较的趟数是可以减少的,因此尽可能减少比较的趟数是算法优化的方向,也是KMP算法的核心思想。那么,让我们开始KMP算法的讲解。

KMP算法详解

KMP算法于1977年被提出,全称 Knuth–Morris–Pratt 算法,包含了三位前辈名字,分别是:Donald Knuth(K), James H. Morris(M), Vaughan Pratt(P)01算法核心思想

如何减少匹配的趟数呢?其实在每一次匹配过程中,我们就能够判断后续几次匹配是否会成功,算法的核心就是每次匹配过程中推断出后续完全不可能匹配成功的匹配过程,从而减少比较的趟数,如图所示:

因此,第一次匹配过之后,就可以得出可以直接跳到第四趟再进行判断的结论了。因为第一次匹配的时候,前5个序列和主串相同,只需要对模式串进行分析,模式串出现了重复单元(即AB),在第一次匹配失败后就可以直接跳跃到出现重复单元的位置。

2next数组

next数组实质上就是找出模式串中前后字符重复出现的个数,为了能够跳跃不可能匹配的步骤。
next数组的定义为:next[i]表示模式串A[0]至A[i]这个字串,使得前k个字符等于后k个字符的最大值,特别的k不能取i+i,因为字串一共才i+1个字符,自己跟自己相等毫无意义。

最终得到next数组为:

如何确定在移动过程中需要跳过多少步呢?下图更直观的体现了跳跃的过程:

对于上述红色部分的计算跳过长度的公式为跳过的趟数=匹配上字符串中间字符长度-重复字符串长度

跳过这些步骤后并非再从头开始匹配,而是从重复位置开始匹配

最终,我们不难得出如下结论:

3python代码实现

1.首先建立KMP对象,初始化参数:

2.建立next数组:

第一种最简单的构建方案,时间复杂度为O(m平法)

第二种构建方案,是一种递推的方式进行构建,时间复杂度为O(n+m):
考虑:如果next[0], next[1], ... next[x-1]均已知,那么如何求出 next[x] ?我们已经知道next[x-1],标记next[x-1]=temp,则可以讨论A[temp]和A[x]的值,分2种情况讨论:
第一种情况:A[temp]等于A[x],也就是说在前一个next结果上又多了一个字符串相同的长度,因此next[x]为next[x-1]+1

第二种:当A[temp]和A[x]不相等的时候,我们需要缩小temp,把temp变成next[temp-1],直到A[temp]=A[x]为止。A[now]=A[x]时,就可以直接向右扩展了。

递推构建next数组代码如下:

3.检索过程代码:

4.测试代码:

作者原创,未经授权请勿转载

3算法全称_全网最通俗的KMP算法图解相关推荐

  1. 经典算法题每日演练——第七题 KMP算法

    原文:经典算法题每日演练--第七题 KMP算法 在大学的时候,应该在数据结构里面都看过kmp算法吧,不知道有多少老师对该算法是一笔带过的,至少我们以前是的, 确实kmp算法还是有点饶人的,如果说红黑树 ...

  2. 机器学习算法 拟合曲线_制定学习曲线以检测机器学习算法中的错误

    机器学习算法 拟合曲线 机器学习 (Machine Learning) The learning curve is very useful to determine how to improve th ...

  3. otsu阈值分割算法原理_大津二值化算法OTSU的理解

    otsu 大津算法介绍: OTSU算法是由日本学者OTSU于1979年提出的一种对图像进行二值化的高效算法. 利用阈值将原图像分成前景,背景两个图象. 前景:用n1,csum,m1来表示在当前阈值下的 ...

  4. fp算法例题_机器学习(九)—FP-growth算法

    本来老师是想让我学Hadoop的,也装了Ubuntu,配置了Hadoop,一时间却不知从何学起,加之自己还是想先看点自己喜欢的算法,学习Hadoop也就暂且搁置了,不过还是想问一下园子里的朋友有什么学 ...

  5. python路径规划算法可视化_路径规划问题:DIJKSTRA算法 以及Python实现

    一. DJKSTRA算法概述 我们可以将地图抽象为Graph的数据结构,然后利用Graph的广度优先遍历算法(Breadth-First Search, BFS)解决无权重的High-Level的地图 ...

  6. 聚类算法 距离矩阵_论文阅读9——AP聚类算法

    Affinity Learning for Mixed Data Clustering 论文提出了基于混合对数据进行聚类的学习框架,具体研究内容包括:1)如何处理具有混合类型属性的数据.2)如何学习数 ...

  7. 三维图形几何变换算法实验_基于深度学习的三维重建算法综述

    点击上方"计算机视觉life",选择"星标" 快速获得最新干货 00 前言 目前,三维重建技术已在游戏.电影.测绘.定位.导航.自动驾驶.VR/AR.工业制造以 ...

  8. rrt算法流程图_基于RRT的运动规划算法综述

    基于 RRT 的运动规划算法综述 1. 介绍 在过去的十多年中, 机器人的运动规划问题已经收到了大量的关注, 因为机器人开始成 为现代工业和日常生活的重要组成部分. 最早的运动规划的问题只是考虑如何移 ...

  9. 可能是全网最清晰的KMP算法讲解

    字符串匹配 "字符串A是否为字符串B的子串?如果是,出现在B的什么位置?"这个问题就是字符串匹配问题.字符串A称为模式串,字符串B称为主串. 那么,如何查找模式串在主串中的位置呢? ...

最新文章

  1. HTTP报文(待整理)
  2. python爬虫beautifulsoup实例-Python爬虫学习(二)使用Beautiful Soup库
  3. 表达式求值问题 数据结构_【每日一题51】实际问题与一次函数 看图象求表达式 由表达式求值...
  4. vue垂直布局_vue实现长图垂直居上 vue实现短图垂直居中
  5. 2 s锁是什么_《演员请就位》:一场戏拿了2张S卡,任敏凭什么打败老戏骨?
  6. RocketMQ是怎么存储消息的?
  7. 服务重构理解接口编程的妙处
  8. [ 2022年4月8日更新 ]Typecho Handsome主题美化教程
  9. useradd - 帐 号 建 立 或 更 新 新 使 用 者 的 资 讯
  10. 洛谷——P1161 开灯
  11. PCTFREEITLCONSISTANT READ
  12. 2010 年下半年系统分析师案例分析真题
  13. 技术支持团队应该是一个斜杠的团队
  14. Qt源码分析--QPaintEngine
  15. 手机应用使用情况监控统计APP
  16. 使用单线程还是多线程的问题
  17. URL中的特殊格式进行转换
  18. 逆向工程--苹果移动端app逆向分析技术(一)
  19. Flash Play 闪玩
  20. python+OpenCV视频检测+代码以及注解

热门文章

  1. 如何修改Cypress 测试代码中默认的超时时间(timeout)
  2. 如何自定义SAP Spartacus的路由路径
  3. rxjs 里的map operator
  4. 获取SAP Spartacus当前显示产品json数据的又一办法
  5. 如何免费申请并使用SAP Marketing Cloud测试系统
  6. filter operation implementation in SAP Gateway framework
  7. Uncaught SyntaxError: Unexpected token in body onload
  8. SAP CRM WebClient UI界面防止XSS攻击的保护措施
  9. 另一种ABAP解析XML file的方式
  10. 如何从ERP下载Sales BOM到CRM