KMP算法最浅显理解(小白教程)
什么是KMP算法?
KMP算法(Knuth-Morris-Pratt算法)是一种字符串匹配算法,用于在一个主串中查找一个模式串的出现位置。与朴素的字符串匹配算法相比,KMP算法具有更高的效率。
KMP算法的基本思想
KMP算法的基本思想是利用已经匹配过的部分信息,避免不必要的回溯。它通过构建一个部分匹配表(Partial Match Table),来记录模式串中的前缀和后缀的最长公共部分长度,从而在匹配过程中跳过一些不可能匹配的位置。
构建部分匹配表
部分匹配表是KMP算法的核心,它记录了模式串中每个位置的最长公共前缀后缀长度。下面是构建部分匹配表的步骤:
- 初始化部分匹配表,长度与模式串相同,初始值都为0。
- 从模式串的第二个字符开始,依次计算每个位置的最长公共前缀后缀长度。
- 对于每个位置i,假设前缀为P[0:i-1],后缀为P[1:i],计算它们的最长公共部分长度。
- 如果P[0:i-1]的最长公共部分长度为k,且P[i-1]等于P[k],则P[0:i]的最长公共部分长度为k+1。
- 如果P[0:i-1]的最长公共部分长度为k,且P[i-1]不等于P[k],则需要继续向前寻找更短的公共前缀后缀。
- 如果P[0:k-1]的最长公共部分长度为m,且P[i-1]等于P[m],则P[0:i]的最长公共部分长度为m+1。
- 如果P[0:k-1]的最长公共部分长度为m,且P[i-1]不等于P[m],则继续向前寻找更短的公共前缀后缀,直到找到长度为0的公共前缀后缀。
- 重复步骤3,直到计算完所有位置的最长公共前缀后缀长度。
KMP算法的匹配过程
KMP算法的匹配过程如下:
- 初始化主串的位置i为0,模式串的位置j为0。
- 逐个比较主串和模式串的字符:
- 如果主串的字符和模式串的字符相等,则继续比较下一个字符。
- 如果主串的字符和模式串的字符不相等:
- 如果j等于0,表示模式串的第一个字符就不匹配,将i加1。
- 如果j大于0,表示已经匹配了j个字符,但第j+1个字符不匹配,根据部分匹配表,将j更新为部分匹配表中j位置的值,继续比较主串的字符和模式串的字符。
- 如果模式串的位置j等于模式串的长度,表示匹配成功,返回主串中匹配的起始位置。
- 如果主串的位置i等于主串的长度,表示匹配失败,返回-1。
示例说明
示例1
主串:\"ABABABABCABABABABD\"
模式串:\"ABABABD\"
构建部分匹配表:
位置 | 字符 | 部分匹配值 |
---|---|---|
0 | A | 0 |
1 | B | 0 |
2 | A | 1 |
3 | B | 2 |
4 | A | 3 |
5 | B | 4 |
6 | D | 0 |
匹配过程:
- 第一步:i=0, j=0,A和A匹配。
- 第二步:i=1, j=1,B和B匹配。
- 第三步:i=2, j=2,A和A匹配。
- 第四步:i=3, j=3,B和B匹配。
- 第五步:i=4, j=4,A和A匹配。
- 第六步:i=5, j=5,B和B匹配。
- 第七步:i=6, j=6,D和D匹配。
- 匹配成功,返回主串中匹配的起始位置为3。
示例2
主串:\"ABCABABABD\"
模式串:\"ABABABD\"
构建部分匹配表:
位置 | 字符 | 部分匹配值 |
---|---|---|
0 | A | 0 |
1 | B | 0 |
2 | A | 1 |
3 | B | 2 |
4 | A | 3 |
5 | B | 4 |
6 | D | 0 |
匹配过程:
- 第一步:i=0, j=0,A和A匹配。
- 第二步:i=1, j=1,B和B匹配。
- 第三步:i=2, j=2,C和A不匹配,根据部分匹配表,j更新为2。
- 第四步:i=2, j=2,C和A不匹配,根据部分匹配表,j更新为1。
- 第五步:i=2, j=1,C和B不匹配,根据部分匹配表,j更新为0。
- 第六步:i=2, j=0,C和A不匹配,将i加1。
- 第七步:i=3, j=0,A和A匹配。
- 第八步:i=4, j=1,B和B匹配。
- 第九步:i=5, j=2,A和A匹配。
- 第十步:i=6, j=3,B和B匹配。
- 第十一步:i=7, j=4,A和A匹配。
- 第十二步:i=8, j=5,B和B匹配。
- 第十三步:i=9, j=6,A和D不匹配,根据部分匹配表,j更新为0。
- 第十四步:i=9, j=0,A和A匹配。
- 第十五步:i=10, j=1,B和B匹配。
- 第十六步:i=11, j=2,A和A匹配。
- 第十七步:i=12, j=3,B和B匹配。
- 第十八步:i=13, j=4,A和A匹配。
- 第十九步:i=14, j=5,B和B匹配。
- 第二十步:i=15, j=6,A和D不匹配,根据部分匹配表,j更新为0。
- 第二十一步:i=15, j=0,A和A匹配。
- 第二十二步:i=16, j=1,B和B匹配。
- 第二十三步:i=17, j=2,A和A匹配。
- 第二十四步:i=18, j=3,B和B匹配。
- 第二十五步:i=19, j=4,A和A匹配。
- 第二十六步:i=20, j=5,B和B匹配。
- 第二十七步:i=21, j=6,A和D不匹配,根据部分匹配表,j更新为0。
- 匹配失败,返回-1。
以上就是KMP算法的最浅显理解,希望对你有帮助!
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:KMP算法最浅显理解(小白教程) - Python技术站