【学习笔记】KMP算法(字符串匹配优化算法)

KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt提出的,因此人们称它为克努特—莫里斯—普拉特操作(简称KMP算法)。

KMP算法的作用是,在一个长字符串内匹配一个短字符串(判断str1.contains(str2))时,减少匹配的次数,提高匹配效率。


 理论上,KMP算法更加优秀,但实际进行字符串匹配时,很多情况下str2往往都很短,直接使用暴力法或BM算法,表现会更好。因此,很多程序语言内置的匹配都是使用暴力法或BM算法。


 

必要概念:最长公共前后缀

字符串“asdas”中,前缀有[a, as, asd, asda],后缀有[s, as, das, sdas],公共部分为[as],最长公共前后缀即为“as”(如果公共部分有多个,则取最长的一个)。

必要概念:Next数组

字符串asdas的所有左子串为[a, as, asd, asda, asdas],这些子串的最长公共前后缀的长度组成的数组[0, 0, 0, 1, 2],即为KMP算法所需的Next数组。


 

 原始字符串匹配(暴力法)思路:

str1:asdmasdasb

str2:asdas

从str1的第0位、str2的第0位开始,向右一个字符一个字符比较,比较到第3位(m对a)时发现不匹配,则起始位置退回到str1第1位、str2的第0位,再次往后比较,以此类推。

 

KMP算法思路:

在比较中途发现不完全匹配时,不用退回到str1起始位置的下一位,而是直接接着str1当前位置,同时将str2的位置退回到当前已匹配子串的最长公共前后缀的下一位。

原理如下:

str1:zxzxzxcv

str2:zxzxc

从两者的第0位开始比较,一直比较到第4位(z对c)发现不匹配。

此时已匹配子串位zxzx,其最长公共前后缀为zx,长度为2。

str1接着在第4位(zxzx[z]xcv)的z,str2回退到第2位(zx[z]xc)中的z,继续往后一个一个比较。

在本例中,继续往后比较即可匹配成功zx[zxzxc]v。

如果再出现不匹配,重新根据已匹配子串进行回退即可。

Next数组的作用,则是在开始匹配之前,先一次性计算出str2的所有左子串的最长公共前后缀,在比较发现不匹配时,直接读取对应的数值,来回退到对应的位置即可。

 

posted @   AsrielMao  阅读(58)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
点击右上角即可分享
微信分享提示