算法原理:
KMP模式匹配算法的思想是减少主串S下标i值的回溯,确定字串T下标j值的变化。
next数组值推导:
KMP模式匹配算法的代码如下:
/* 通过计算返回子串T的next数组 */
void get_next(String T, int *next)
{
int i,j;
i = 1;
j = 0;
next[1] = 0;
while(i < T[0]) //此处T[0]表示串T的长度
{
if(j == 0 || T[i] == T[j]) //T[i]表示后缀的单个字符,T[j]表示前缀的单个字符
{
++i;
++j;
next[i] ==j;
}
else
j = next[j]; //若字符不相同,则j值回溯
}
}
上面这段代码的目的是得出当前要匹配的串T的next数组。
/* 返回子串T在主串S中第pos个字符之后的位置,若不存在,则函数返回值为0 */
int Index_KMP( String S, String T, int pos)
{
int i = pos; //i用于主串S当前位置下标值,若pos不为1,则从pos当前位置开始匹配
int j = 1; //j用于子串T中当前位置下标值
int next[255]; //定义一个next数组
get_next(T,next);
while(i <= S[0] && j<= T[0])
{
if(j==0||S[i]==T[j])
{
++i;
++j;
}
else
{
j=next[j];
}
}
if(j>T[0])
return i-T[0];
else
return 0;
}
相对于朴素匹配算法而言,i值回溯的部分被移除了。对于get_next函数来说,若T的长度为m,其时间复杂度为O(m),而while循环时间复杂度为O(n)。因此,整个算法的时间复杂度为O(m+n)。相较于朴素匹配算法O((n-m+1)*m)要好一些。