通俗易懂的KMP理论讲解(含手求Next数组)
1.KMP算法介绍
KMP算法的核心是利用匹配失败后的信息,通过一个 next 数组,保存模式串中前后最长公共子序列的长度,尽量减少模式串与主串的匹配次数降低时间复杂度以达到快速匹配的目的。
2.字符串的前后缀与公共前后缀
2.1字符串的前缀
字符串的前缀是指不包含最后一个字符的所有以第一个字符(索引为0)开头的连续子串。
例:字符串“ABCD”的前缀有A,AB,ABC。
2.2字符串的后缀
字符串的后缀是指不包含第一个字符的所有以最后一个字符结尾的连续子串。
例:字符串“ABCD”的后缀有BCD,CD,D。
2.3公共前后缀
公共前后缀是指一个字符串的所有前缀连续子串和所有后缀连续子串中相等的子串。
例:字符串“ABABA”
前缀有:A,AB,ABA,ABAB
后缀有:BABA,ABA,BA,A
因此公共前后缀有:A ,ABA
2.4最长公共前后缀
最长公共前后缀是指所有公共前后缀的长度最长的那个子串。
例如字符串 “ABABA” ,公共前后缀有:A ,ABA
ABA是三个字符长度,A是一个字符长度,那么最长公共前后缀就是ABA
3.手求Next数组
第一种方法(亲测好用):
示例:串“ababaa”的next数组为()。
解析:首先,搬出我们总结的真理:
串的第一位和第二位字符对应的next值分别为固定值0、1
串的其他位对应的next值为该字符之前的字符串的公共最长匹配前缀和后缀的长度加1
※对于从索引为0开始的子串“ab”而言:
前缀:不包含最后一个字符b的所有以第一个字符a开头的连续子串有a。
后缀:不包含第一个字符a的所有以最后一个字符b结尾的连续子串有b。
因此该子串的最长公共前后缀的长度为0然后将该值进行+1操作得到对应的next值为1。
※对于从索引为0开始的子串“aba”而言:
前缀:不包含最后一个字符a的所有以第一个字符a开头的连续子串有a,ab。
后缀:不包含第一个字符a的所有以最后一个字符a结尾的连续子串有ba,a。
因此该子串的最长公共前后缀长度为1然后将该值进行+1操作得到对应的next值为2。
※对于从索引为0开始的子串“abab”而言:
前缀:不包含最后一个字符b的所有以第一个字符a开头的连续子串有aba,ab,a。
后缀:不包含第一个字符a的所有以最后一个字符b结尾的连续子串有bab,ab,b。
因此该子串的最长公共前后缀长度为2然后将该值进行+1操作得到对应的next值为3。
※对于从索引为0开始的子串“ababa”而言:
前缀:不包含最后一个字符a的所有以第一个字符a开头的连续子串有abab,aba,ab,a。
后缀:不包含第一个字符a的所有以最后一个字符a结尾的连续子串有baba,aba,ba,a。
因此该子串的最长公共前后缀为3然后将该值进行+1操作得到对应的next值为4。
所以串“ababaa”的next数组为:011234
第二种方法(网上看到的,本人还不是很理解,有懂的人可以说一下):
以下部分转载自知乎作者:Nick
链接:https://www.zhihu.com/question/62030859/answer/835271234
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
示例:求串“a b a a b c a c”的next数组。
这是一个考试常见的字符串,是如何计算的那?第n位:next[n]的值来自于第n-1位的字符,通过跟第next[n-1]位字符比较,如果相同next[n]=next[n-1]+1,如果不相同,就跟第next[next[n-1]]位的字符比较,就这样迭代直到相同的时候,加上1,如果实在没有,就为1.这一段话可能很难理解,逐位分析。让我们从依次来看:第3位:第2位和第1位比较,不相同 所以为1第4位:第3位和第1位比较,相同,所以为2第5位:第4位和第2位比较,不相同,和第1位比较,相同,所以为2第6位:第5位和第2位比较, 相同,所以为3第7位:第6位和第3位比较,不同,和第1位比较,不同,所以为1第8位:第7位和第1位比较,相同,所以为2.
需要打印的可以点击链接下载文档文件:通俗易懂的KMP理论讲解(含手求Next数组).pdf - 蓝奏云
创作不易,点赞关注一下吧。