最近对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则是这样的操作进行若干次,直到上面那个串对比完。对比成功的标志就是下面的串对比完。
这样是不是就省去了大量多余的对比呢?
画图可以这样画,写程序会有选择下一次对比点的初始化操作。图示只是大意,细节请看文章开头推荐的链接。
工作时最喜欢画这样的图或写文字,而不是程序员通常画的流程图,感觉那东西不太符合人的思维模式,当然,有可能只是我的。
转载请注明出处,谢谢。