【学习笔记】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的所有左子串的最长公共前后缀,在比较发现不匹配时,直接读取对应的数值,来回退到对应的位置即可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架