KMP算法
来源:互联网 发布:win10 64位下载 知乎 编辑:程序博客网 时间:2024/05/18 21:07
KMP算法是一种字符串匹配的高效算法,简单的匹配算法(BF算法)时间复杂度为O(m*n),KMP算法的时间复杂度为O(m+n)。
例如:当主串S为ABCDEFGH,匹配串T为ABCDX。(其中数组下标0来存放字符串长度)
其中E与X不匹配,按照BF算法,应该S串右移一位,T串重新回到开始即:
但是因为j[1]!=j[2],i[1]=j[1],i[2]=j[2],所以不用比较就可以知道j[1]肯定不等于i[2]。按照KMP算法直接将j[1]与i[5]比较即:
当主串是AAABD,匹配串是AAB。
可以看出i[3]与j[3]失配,根据KMP算法,因为j[1]=j[2],i[2]=j[2],所以i[2]=j[1],因此要这样匹配
当主串是AABAAC,匹配串是AAC,即
按照原理应该这样匹配
我们可以创建一个next数组,指导模式匹配串下一步改用第几号元素进行匹配。如上述第一个例子:
如果是例子二:
可以得出一个结论:KMP算法问题是由模式串决定,而不是主串决定。
如何来求next数组呢?
首先应该明白前缀和后缀的概念。"前缀"指除了最后一个字符以外,一个字符串的全部头部组合;"后缀"指除了第一个字符以外,一个字符串的全部尾部组合。
例如字符串ABABAAB。
”A“的前缀和后缀都为空集,共有元素的长度为0,next数组填1
“AB”的前缀为A后缀为B,共有元素的长度为0,next数组填1
“ABA”的前缀为A,AB,后缀为BA,A,共有元素长度为1,next数组填2
“ABAB”的前缀为A,AB,ABA,后缀为B,AB,BAB,共有元素为长度为2,next数组填3
“ABABA”的前缀为A,AB,ABA,ABAB,后缀为A,BA,ABA,BABA,共有元素长度为3,next数组填4
“ABABAA”的前缀为A,AB,ABA,ABAB,ABABA,后缀为A,AA,BAA,ABAA,BABAA,共有元素长度为1,next数组填2.
如图所示:
求next数组源码如下:
void get_next( String T, int *next ){ //i后缀,j前缀int j = 0;int i = 1;next[1] = 0;while( i < T[0] ) //当后缀等于串的长度,匹配完成{if( 0 == j || T[i] == T[j] ){i++;j++;if( T[i] != T[j] ){next[i] = j;}else{next[i] = next[j];}}else{j = next[j]; //若不相等回溯到上一次匹配的位置}}}
KMP算法源码:
// 返回子串T在主串S第pos个字符之后的位置// 若不存在,则返回-1int Index_KMP( String S, String T, int pos ){int i = pos;int j = 1;int next[255];get_next( T, next );while( i <= S[0] && j <= T[0] ){if( 0 == j || S[i] == T[j] ){i++;j++;}else{j = next[j]; //若不匹配}}if( j > T[0] ){return i - T[0];}else{return -1;}}
- KMP算法详解 【KMP】
- 【KMP】KMP算法模板
- KMP hihoCoder1015 KMP算法
- kmp算法
- KMP算法
- KMP算法
- KMP算法
- KMP算法
- KMP 算法
- kmp算法
- KMP算法
- kmp算法
- KMP算法
- KMP算法
- kmp算法
- kmp算法
- KMP算法
- KMP算法
- POJ 1018 Communication System (枚举+贪心)
- CF_292_C_Drazil and Factorial_数学
- 寒假学习总结
- OpenWorm
- Tyvj专题 数字三角形
- KMP算法
- C# 类以及对象
- Tyvj专题 P1159 玛丽卡
- oracle 11g忘记sys用户密码
- Leetcode: Minimum path sum
- CF_292_D_ Drazil and Tiles_贪心、dfs
- Tyvj专题 P1337 fibonacci数列
- VC++动态链接库(DLL)编程深入浅出(zz)
- 【JAVA实现】基于皮尔逊相关系数的相似度计算