getnext(可理解为模式串自匹配)
void Getnext(String t,int next[])
{
int j = 0, k = -1;
next[0] = -1;
while(j < t.length - 1)
{
if(k == -1 || t[j] == t[k])
{
j++;
k++;
next[j] = k;
}
else k = next[k];
}
}
配图理解
- 不妨把看作目标串,看作模式串
- next [j] = k,代表j 之前的字符串中有最大长度为k 的相同前缀
- 关于k串
- k的数值要么按++方式递增,要么快速回退
- k=-1表示需要从头进行匹配
- j串和k串第一个字符一定是相符的,所以第一个字符前面一定没有相同前缀,k串初始化为-1
- 在k=-1时,next[j+1]=k+1=0,前面一定没有相同前缀,从t[j+1]和t[k+1]位置再开始比较
- k不断地赋初值,一定有k<j, 所以 next[k] 必然有记录,k位置失配不妨使k=next[k],向前回退
- j一直后移使得可以判断出模式串所有位置的next函数
KMP
int KMP(String s, String t)
{
int next[MaxSize], i = 0, j = 0;
Getnext(t, next);
while(i < s.length && j < t.length)
{
if(j == -1 || s[i] == t[j])
{
i++;
j++;
}
else j = next[j]; //j回退。。。
}
if(j >= t.length)
return (i - t.length); //匹配成功,返回子串的位置
else
return (-1); //没找到
}
算法性能分析
- 时间复杂度:O(m+n),m是目标串长度,n是模式串长度