大家好,我是一个每天在互联网都被读者催更催到爆肝,爆肾小鹿童鞋。

说实话,一些数据结构和算法我这辈子都不可能用到实际当中,但个人一直觉得能把复杂的东西讲明白是一件很牛逼的事情。

毕竟想牛逼也是很难的,并不是我说了算,前几天更新的的 BF 和 RK 算法,就被后台小伙伴的留言疯狂石锤,哼!你牛逼你就讲讲 KMP 算法,我要石锤。

这几天吓得俺吃饭吃不消,睡觉睡不香,干啥啥不行,这无数的与 KMP 战斗的夜晚。今天他来了,他带着 KMP 来了。讲就讲,今天不讲明白你们谁都别想走,放学都在学校门口等着。

(为了能够让大部分读者对 KMP 的基本原理,文中不具体分析代码实现)

什么是 KMP?

听说 KMP 算法是一种字符串的改进算法,嗯~ 字符串匹配算法还有啥?不好意思,记性不好,居然忘记了。咱们继续,KMP 算法是由D.E.Knuth,J.H.Morris 和 V.R.Pratt 发明的,至于名字怎么读,四级没过,反正我不认识。

这都不重要,重要的是 KMP 算法的核心,它是主要利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。

嗯~ 听起来比暴力破解法牛逼的多,至于如果快速匹配的,还需要深入研究一下。

KMP的由来?

在一个夜黑风高的夜晚,我翻看了全网的 KMP ,读了一遍又一遍,还是看不懂,不知吃了多少碗泡面之后,突然灵感来了,

我快速打开编辑器,写下了两行测试字符。

如果由以上模式串和子串,子串要在模式串中做一个字符串匹配,一般的匹配过程如下:

当我们遇到最后一个字符匹配 E 与 D 并不能完全匹配,那么我们开始往后移动子串一个,一个个重新进行比较。

然而发现第一个字符就不能匹配成功,那好吧,继续往后移动子串。

直到移动到下面这种情况,虽然匹配了 A 和 B,但是到了第三个字符,E 和 C 又不能匹配了,真伤心,好不容易匹配成功前两个。

通过以上,我们发现暴力匹配,就算前几个已经匹配成功,但是由于最后匹配失败导致了重新移动一位,这也太浪费时间了。

既然我们知道前几位匹配的信息。比如第一次匹配,我们知道了已经成功匹配了 ABCAB 了。能不能利用已经知道的匹配信息进行析,然后一次性往后移动多位呢?

KMP 原理

实话告诉你,没有。但是这几个人做到了,分别是 K 某,M 某,P某的三个人,不愧是大佬中的传奇人物,我就咋没想到呢?这次又被石锤智商低下了。

但是我们想象能力还是挺强的,假如有一个神奇的“表”,我们暂且起名叫做匹配表吧,那么我们每次移动的次数,这个神奇的表能够告诉我们,我们岂不是美滋滋的往后移动多位进行快速匹配不就可以了吗?

尼玛尼玛哄,你骂谁呢?不好意思,错了,重来,玛尼玛尼哄,这张神奇的匹配表说来就来。

虽然这个表目前是幻想出来的,无关紧要,我们再试着匹配一次上边用到的字符串。

开始正式匹配,匹配到 E 和 D 就卡壳了,既然有了神奇的匹配表,不需要一个个的移动了,我们应该问一下神奇的“表”,魔表魔表,下一步应该把子串移动多少位?

此时匹配表进行疯狂的计算,对于如何计算,也告诉我们公式了。它来询问你,这才字符匹配成功匹配了几个字符,很容易在图中得到,ABCAB 共 5 位匹配成功。

然后又问,这五位中最后一位是谁?当然是 B 了,那么 B 在匹配表中的匹配值是多少?稍等,我看看匹配表哈~ 嗯~ 这个 B 对应的是 2。

好了,用成功匹配的位数减去匹配值就是下一次要移动的次数。

纳尼?这么神奇?然后我就傻了吧唧相信了去试了试,测试过程如下。

嗯~ 5 - 2 等于 3,所以我要将子串移动四位,如下图位置。

然后我再进行匹配,当遇到 E 与 C 的时候,匹配失败,此时已经匹配了两个元素,分别为 AB,那下一次要往后移动多少呢?

还是按照上边的方式计算,已匹配 2 的字符,此时已匹配字符 AB 最后一个字符是 B,所以这个 B 对应的匹配表的匹配值为0,往后移动 2-0等于 2,往后移动两位。

继续匹配,发现第一个字符就匹配失败了,继续移动一位,最后发现全匹配。

整体的 KMP 算法就是这么一个思路,但是我们所用到的这个匹配表示我们想象出来的,能不能计算出来呢?理想总是很美好,但现实很骨感。

计算匹配表

首先要弄懂两个概念,就是前缀和后缀的概念。

对于我们的子串来说,它的前缀有哪些呢?对于前缀就是除了最后个字符以外所有的顺序组合方式。比如 A、AB、ABC、ABCA、ABCAB。

后缀正好相反,除了第一个字符外,其他所有的组合方式。比如BCABD、CABD、ABD、ABD、BD、D。

对于每个匹配值是如何计算的,那就对子串的每个字符组合寻找出前缀和后缀,然后进行比较是否有相同的,相同的字符组合有几位,就是所谓的匹配值。

这样纯文字说可能很懵逼,直接上图。

我们可以在图中发现,并没有对子串移动的规律发现任何问题,但是我们在看一下子串。

突然恍然大悟,从上图中发现有时候在同一字符串中出现两种相同的字符,比如上图中的 AB,由两个字符组成的,所以匹配值为 2,同时在匹配的过程中,如果 D 前边的字符能够匹配,则子串往后移动 3 位,则再次匹配 AB,原来这是 KMP 的精髓所在。

数据结构 kmp字符串匹配_用动画解释 KMP 算法相关推荐

  1. 落谷 P3375 【模板】KMP字符串匹配

    题目描述 如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置. 为了减少骗分的情况,接下来还要输出子串的前缀数组next. 输入格式: 第一行为一个字符串,即为s1 ...

  2. Oulipo-欧力波(KMP字符串匹配问题)

    Oulipo-欧力波 HDU - 1686 The French author Georges Perec (1936–1982) once wrote a book, La disparition, ...

  3. Simpsons’ Hidden Talents辛普森一家的隐藏天赋(next数组和kmp字符串匹配)

    辛普森一家的隐藏天赋 HDU - 2594 目录 辛普森一家的隐藏天赋 HDU - 2594 题意描述:当给定字符串s1和s2时,找到s1中最长的前缀,即s2的后缀.如果有,输出相同的字符串即字符串长 ...

  4. KMP算法小总结 洛谷P3375 【模板】KMP字符串匹配

    提问:这里有一个长度为n的字符串str1和长度为m的字符串str2(n > = m),问在str1中str2出现了几次? 如果使用暴力求解,一个一个比较,在n和m都极大的情况下将花费非常多的不必 ...

  5. 大量的数据做字符串匹配_【重学数据结构与算法(JS)】字符串匹配算法(三)——BM算法...

    前言 文章的一开头,还是要强调下字符串匹配的思路 将模式串和主串进行比较 从前往后比较 从后往前比较 2. 匹配时,比较主串和模式串的下一个位置 3. 失配时, 在模式串中寻找一个合适的位置 如果找到 ...

  6. # 字符串从右往左查找_字符串匹配(搜索,查找)算法

    (一)前言 所谓的字符串匹配就是在一个长字符串(可称文本T)中找一个短字符串(可称模式P),看长字符串中是否存在短字符串,若存在则返回出现的第一个位置,若不存在则返回一个标记.字符串搜索算法有很多,比 ...

  7. 【模板】KMP字符串匹配

    题目描述 给出两个字符串 s_1s1​ 和 s_2s2​,若 s_1s1​ 的区间 [l, r][l,r] 子串与 s_2s2​ 完全相同,则称 s_2s2​ 在 s_1s1​ 中出现了,其出现位置为 ...

  8. 数据结构-数组-字符串匹配:Knuth-Morris-Pratt算法(详解附完整代码)

    字符串匹配 字符串抽象数据类型 字符串模式匹配 简单的字符串匹配 Knuth-Morris-Pratt算法 背景分析 失配函数 定义 实现方法 函数分析 KMP函数 实现方法 函数分析 失配信息的另一 ...

  9. KMP算法详解P3375 【模板】KMP字符串匹配题解

    KMP算法详解: KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt(雾)提出的. 对于字符串匹配问题(such as 问你在abababb中有多少个 ...

最新文章

  1. 企业中常用的几种文件传输方法介绍
  2. 压力测试工具gatling安装和介绍
  3. 由浅到深了解JavaScript类
  4. MFC获得主窗体和父窗体指针
  5. 实战NFS服务搭建与配置
  6. html标签处理数据时合并空格
  7. 根据经纬度计算范围_地理计算专题(上)
  8. python string模块template_Python标准库笔记(1) — string模块
  9. C++11 bind注意事项(传引用参数的时候)
  10. 导入项目到IDEA报javax/xml/bind/DatatypeConverter错误?
  11. python编写扫描工具_python编写类似nmap的扫描工具
  12. java参数传入数组_java传入数组参数
  13. swagger注解说明_齐全的swagger注解介绍
  14. verilog版的1602+ps2
  15. Common Data Model (CDM)通用数据模型1
  16. android studio 配置+安装
  17. 宜信笔试题 把m升水倒入n个杯子
  18. php socket获取客户端IP地址
  19. 十一、Word参考文献的跳转引用
  20. 第一时间看透对方:FBI 教你破解身体语言(美)乔·纳瓦罗,马文·卡尔林斯

热门文章

  1. 不能分配USB设备Generic USB3.0 Card Reader[]到虚拟电脑Ubantu
  2. 什么牌子投影仪好?国产投影仪什么牌子好
  3. 多媒体设计计算机音乐创作原创音乐,多媒体设计计算机音乐创作原创音乐[计算机辅助音乐创作教学,改善课堂教学效果].doc...
  4. SP 为模型加上法线贴图并未贴图上色
  5. java抽象类和接口有什么意义
  6. 华农兄弟、徐大Sao李子柒?谁才是B站美食区的最强王者?
  7. Java版mc映射局域网联机教程
  8. linux 多核 arm,ARM big.LITTLE巨细核架构在Linux和Android内核下多核调度算法
  9. FLASH网络游戏基本知识-flash和后台的简单socket链接2009-10-08 11:43FLASH网络游戏主要解决的是和服务器的数据传输问题
  10. iOS app崩溃率,如何解决线上闪退