KMP算法通俗讲解

最近对KMP算法好奇,这算法完全没印象(学校教过,但我没学,因为逃课),也不是还给了老师。只是想跳槽的话,听说都得明白这玩意。

在网上找了一篇文章,这哥们应该算是比较出名的,http://www.matrix67.com/blog/archives/115。

刚开始看,一个字“晕”。什么kmp,bf,bm,头都看疼了。仔细看了后才明白。下面说说bf与kmp,没有代码,尽量通俗点讲解。

bf不细说了,这是相当"通俗"及自然(我自己形容为原始想法)的想法,从头到尾比较字符串,不相等则从头再来。bf传送门

当然,你得理解bf算法。kmp就是在bf的基础上,将每次从头来对比这个操作进行优化,让这个操作不要从头,根据之前的对比(这些操作不仅消耗了cpu,还有其它用处,不能浪费),来优化对比的偏移量。当然,也有最坏的情况,还是得从头来。但现实中大部分情况不是这样的。

这里提及一下,以免面试要问,kmp算法复杂度为O(m+n)。

还是给个例子:

A串:   a  b  a b d a b c e h a b c d

B串:     a b a b d(e)

1 2 3 4 5

这个例子一次就会通过对比,但把B串的最后的字符d变成e之后,在对比B串e与A串中d后,bf就会直接从头的a开始对比。而kmp不会,是从第二个b之后的a开始对比,即对比B串的a(下标3)与A串的d(下标5),若相等则比较B串下一个字符,不等则再次从头开始对比,但A串一直往后对比。

为什么会这样呢,用语言说就是之前的对比结果被证明无需再从头对比(貌似是废话)。还是画个图吧,无图无真相不是。

A+B = C + D,且A = B, C = D,当发生e与f不相等的情况时,你会再次从下面那个串的第一个元素开始与上面串的第二个元素对比吗?

不会。你肯定会这样去进行下一次对比。

即把C这部分已经被证实与B相等的部分认为是相等的,只需要把D中的部分与e及后面的部分进行下一次对比,这里看清楚,写的是下一次对比。而kmp则是这样的操作进行若干次,直到上面那个串对比完。对比成功的标志就是下面的串对比完。

这样是不是就省去了大量多余的对比呢?

画图可以这样画,写程序会有选择下一次对比点的初始化操作。图示只是大意,细节请看文章开头推荐的链接。

工作时最喜欢画这样的图或写文字,而不是程序员通常画的流程图,感觉那东西不太符合人的思维模式,当然,有可能只是我的。

转载请注明出处,谢谢。

时间: 2024-07-31 07:36:33

KMP算法通俗讲解的相关文章

KMP算法--通俗易通

public class KMPAlgorithm { public static void main(String[] args) { String str1 = "BBC ABCDAB ABCDABCDABDE"; String str2 = "ABCDABD"; int[] kmpTable = kmpTable(str2); System.out.println(Arrays.toString(kmpTable)); } public static int[

KMP算法精读

看了网上很多KMP算法的讲解,总感到云里雾里,最后翻了翻严蔚敏的<数据结构>终于了解了KMP算法.这里给大家分享一下. 对于很久没碰算法的同学,首先要了解一下最原始的模式匹配算法BF算法.如果是由一定了解的可以直接转到KMP算法. 1.BF算法 算法基本思想就是从主串S开头起,与模式串T的第一个字符比较.若相等,则继续逐个比较字符:否则从主串的开头下一个字符开始重新比较.相当于主串S我要循环S.len长度,比较过程中与模式串T比较也是一个循环,这个循环的次数最多是S.len-1,且每次循环长度

字符串匹配暴力算法 与 字符串匹配的KMP算法

声明:先看一下阮一峰的网络日志关于字符串的KMP算法的讲解.本文图片均引用于这篇日志. 在先前的笔试中遇到了关于字符串匹配的问题,一时脑袋卡壳没写好算法.现在就来分析分析 暴力算法和KMP算法各自原理,以及代码实现,之间差异,并且总结一下好算法的一般思路. =========================================================================== 各自原理: 暴力算法: 1. 我们把长的字符串做为一个文本字符串,命名为strText,把

KMP算法学习记录----《大话数据结构》部分匹配表学习部分

如需转载,请保留本文链接. 首先先将<大话数据结构>关于KMP算法的讲解部分贴上,本文不提供下载链接,也不会将电子书作为资料留百度云,需要电子书的各位,请自行寻找电子版. 关于上述的KMP算法种的next数组的推导部分,一直不是很明白,本贴是关于上述部分的学习推导记录. 以书中字符串为例: 1|2|3|4|5|6|7|8|9| a|b|a|b|a|a|a|b|a| 0|1|1|2|3|4|2|2|3| string T = "ababaaaba"; int i = 1;j

字符串 - KMP算法

字符串算法中,字符串匹配是一个非常重要的应用.例如在网页中查找关键词,其实就是在对字符串匹配,也就是看一个主字符串中是否包含了一个子字符串. 而KMP算法在字符串匹配方法中一个很著名并且很聪明的算法,当然也确实比较难理解.甚至于有程序员因为无法理解KMP算法而直接改用暴力匹配.本身自己学算法起步较晚,第一次接触到KMP算法已经是研究生毕业一年了.虽然带着研究生的学历背景,但是刚开始看的时候依然是一脸懵逼.看了很多博主的讲解总算是明白了,所以在这篇博客中记录下来自己的理解,如果能帮助到别人也是万分

[转]一个比较通俗的KMP算法讲解

最近在学字符串匹配的时候接触了这个算法,算法书上都是我讨厌的下标,转来转去,头晕啊.只好上网搜一下,大部分跟书上一样,好不容易找到一篇,总算看得有些懂了.      其实最简单的字符串匹配,就是逐个逐个比较,但是这样的效率很低,而KMP算法利用了......(不说了,表达能力差啊,^_^,看看牛人怎么解释的吧). 我们这里说的KMP不是拿来放电影的(虽然我很喜欢这个软件),而是一种算法.KMP算法是拿来处理字符串匹配的.换句话说,给你两个字符串,你需要回答,B串是否是A串的子串(A串是否包含B串

【经典算法】&mdash;&mdash;KMP,深入讲解next数组的求解

前言 之前对kmp算法虽然了解它的原理,即求出P0···Pi的最大相同前后缀长度k:但是问题在于如何求出这个最大前后缀长度呢?我觉得网上很多帖子都说的不是很清楚,总感觉没有把那层纸戳破,后来翻看算法导论,32章 字符串匹配虽然讲到了对前后缀计算的正确性,但是大量的推理证明不大好理解,没有与程序结合起来讲.今天我在这里讲一讲我的一些理解,希望大家多多指教,如果有不清楚的或错误的请给我留言. 1.kmp算法的原理: 本部分内容转自:http://www.ruanyifeng.com/blog/201

KMP算法的next[]数组通俗解释

我们在一个母字符串中查找一个子字符串有很多方法.KMP是一种最常见的改进算法,它可以在匹配过程中失配的情况下,有效地多往后面跳几个字符,加快匹配速度. 当然我们可以看到这个算法针对的是子串有对称属性,如果有对称属性,那么就需要向前查找是否有可以再次匹配的内容. 在KMP算法中有个数组,叫做前缀数组,也有的叫next数组,每一个子串有一个固定的next数组,它记录着字符串匹配过程中失配情况下可以向前多跳几个字符,当然它描述的也是子串的对称程度,程度越高,值越大,当然之前可能出现再匹配的机会就更大.

【经典算法】——KMP,深入讲解next数组的求解

前言 之前对kmp算法虽然了解它的原理,即求出P0···Pi的最大相同前后缀长度k:但是问题在于如何求出这个最大前后缀长度呢?我觉得网上很多帖子都说的不是很清楚,总感觉没有把那层纸戳破,后来翻看算法导论,32章 字符串匹配虽然讲到了对前后缀计算的正确性,但是大量的推理证明不大好理解,没有与程序结合起来讲.今天我在这里讲一讲我的一些理解,希望大家多多指教,如果有不清楚的或错误的请给我留言. 1.kmp算法的原理: 本部分内容转自:http://www.ruanyifeng.com/blog/201