(原创)大白话KMP算法详解,一秒get模式匹配

引子:BF暴力算法


KMP算法知名度相当高,燃鹅其理解难度以及代码实现对于初学数据结构和算法的同学并不友好,经过两天的总结,详细总结KMP算法如下:

初学串的模式匹配时,我们都会接触到,或者说应该能想到作为教学引子的BF暴力算法,那么先来简单了解一哈:

我有一个大串是"abccabca",小串是"bca",现在要找到小串在大串中的位置,战斗开始


这个算法理解起来肥肠简单,我在这里假定 i 指针指向大串(主串)的首地址,指针指向小串(模式串)的首地址。首先大串第一位正面对比小串第一位,两元素若相等,则两指针分别后移,继续比较第二位。那么这个算法被称为暴力算法的原因就在于当两串元素对比不相等时,j指针就会回溯到小串的首地址,这本无可厚非,而i指针却会回溯到对比之初的后一位,比如上述第四步大小串匹配不上之后i指针马上来到了第三位,导致了完全无用的第五和第六步比较,造成了算法时间复杂度的加大,而且主串元素数嵌套小串元素数的两重循环,直接造成了O(m*n)的人间大惨案。虽然能实现模式匹配,但是我们的D.E.Knuth、J.H.Morris和V.R.Pratt觉得这个算法有必要改进一哈(V.R.Pratt:嘤嘤嘤),而且出于科学家的身份和*友情缘,三位同时研究出了一个船(全)新的匹配方式,KMP算法横空出世,当然只要体验三分钟,你就会跟我当时一样,放弃这个算法。

附:BF暴力算法代码(取自《大话数据结构》   ps: S[0]、T[0]表示该串的长度)


第一章:kmp算法


黄历上写明了,这个算法不宜先学代码,否则可能会造成理解困难。我这里还是先以一个例子来讲解一下这三个外国同学的算法:

(例子取自《大话数据结构》)

不难发现,我们的模式串没有一个字母是重复出现的,而第一步已经确诊主串和模式串的前五位一模一样,所以你如果这时候使用BF暴力算法,依次用主串的第二位到第五位跟模式串的首位正面刚,就是人傻劲大,完全莫得必要。所以我们要想个办法避免这种重复浪费的现象,结合上面的BF例子,我们也可以明白,这种现象的出现并非是 j 指针的错,而是 i 指针作为主串的指针瞎回溯造成的匹配浪费。

好的,理解了上面的步骤为啥子是多余的,我们再次征讨一下曾被我们用了很长一段时间的暴力算法,正因为它能力有限,只能通过把 i回溯到一个很靠前的位置才能实现匹配,重点来了,这时来了一个叫做KMP的人,告诉你BF能做到的他也能做到,甚至能把时间复杂度降为O(m+n),这个时间复杂度是什么概念,意味着 i 再也不用承受眼看着无用还不得不回溯的命运。我们来看看KMP算法是怎样干掉BF这个老黄牛的。(前方高能,佩戴脑子食用效果更佳)

要想 i 值不回溯,就一定要在 j 上面做文章,我们再次看看上面的例子,如果第一步刚发现 i=6 两串不匹配时,摁住 i 指针,让 i 继续=6 ,然后这时候使j指针回到初始的位置,即 i = 6 时 j = 1,让主串中的 f 和模式串的 a 比较,就很完美辽,那这里也可能有机智的同学问,要是我的模式串中出了一个和首元素相等的元素怎么破?(/手动狗头),不妨看看这个例子,主串是 "abcabcabx", 模式串是"abcabx" ,当然贼符合你的心意,当用BF第一轮比到第六位,发现 c 和 x 不一样,这时你会想,把 i 回溯到第四个元素(即 a),再用 j = 1 直接就出结果。但是你想一想,可否不移动 i ,让 j = 3 直接匹配,况且这个例子只是特殊情况,所以怎样看来都是不必回溯 i的,下面我们看看怎样让 j 发挥他的作用。

既然是 j 的事,就和主串没关系了,我们来研究一下上一段这个例子,我们刚才为什么要移动 j 让他等于3,为了省去模式串前面存在的重复比较,这个重复比较是哪来的呢,就在于 模式串结构中的前后重复程度, "abcabx"这个例子中的串可以分为 "a"+"bcabx" 、"ab"+"cabx"、"abc"+"abx"、"abca"+"bx"、"abcab"+"x",前缀有"a"、"ab"、"abc"、"abca"、"abcab",定义第一个前缀重复度为0,第二个前缀重复度为1,第三个也是1,第四个我们不难发现首尾呼应,所以他的重复度较前面的加一是2,最后一个前缀ab段重复,故重复度为3。

那我们求出这个重复度有毛用呢,我们再看看那个例子,当我们在第一轮发现第六个不相等时,我们可以发现前五位重复度为3,这个3眼熟不,他可以直接在 i 不回溯的前提下把 j 带到正确的位置,即 j = 3,那我们模式串的每一个数都需要这个值来实现KMP算法,我们用一个 next[x] 数组来储存这些数,至于x的大小取决于你的模式串长度。

这时候我们来看看KMP算法的代码(当然还是来自《大话数据结构》的伪码):

这段代码是获得 next数组 的


 敲了芥末多的字,希望大家可以快速理解这个KMP模式匹配算法,未完待续.......

预告第二章:KMP算法的改进版本

届时神秘的nextval数组将浮现江湖

continued

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,014评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,796评论 3 386
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,484评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,830评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,946评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,114评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,182评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,927评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,369评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,678评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,832评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,533评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,166评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,885评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,128评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,659评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,738评论 2 351

推荐阅读更多精彩内容

  • 字符串匹配KMP算法详解 1. 引言 以前看过很多次KMP算法,一直觉得很有用,但都没有搞明白,一方面是网上很少有...
    张晨辉Allen阅读 2,390评论 0 3
  • title: 串的模式匹配算法之kmptags: 数据结构与算法之美author: 辰砂tj 1.引言 首先我们需...
    tojian阅读 967评论 0 0
  • 串匹配算法也称作模式匹配算法,就是在目标字符串中查找子字符串,常用于文本搜索、入侵检测等领域,将目标字符串定义为T...
    效宇笑语阅读 1,408评论 0 1
  • 参考课程:宋会英老师——KMP算法——效率较高的匹配算法D.E.Knuth,J.H.Morris和V.R.Prat...
    jenye_阅读 2,134评论 0 6
  • 时间如白驹过隙,它扮演着导演的角色,明确了主角,选择了配角,也给了路人甲乙镜头。它带走了很多,更留下了不少。主角是...
    王思民阅读 335评论 0 1