KMP算法
KMP算法最重要的就是得到 next 数组,以 next[j]=k 为例,在KMP算法里next数组的意思是下标为 j 的字符失配时模式串要后移到k的位置重新开始比较,在求 next 数组的过程中,我们也可以理解为是前 j 个字符中前缀和后缀的相等的最大长度。
void get_next(string str,int next[])
{
int j=0,k=-1;
next[0]=-1;
while(j<str.length())
{
if(k==-1||str[j]==str[k])
{
j++;
k++;
next[j]=k;
}
else
k=next[k];
}
}
这段代码很简洁易懂,因为如果有 str[j] = str[next[j]] 的话,next[j+1] = next[j] + 1,应该就 k = next[k] 比较难懂,但它其实就是在求 next 数组的过程中又用了 KMP 算法,如果前缀和后缀失配的话,那么本来指向前缀末端的指针(在这段代码里指的是k)就要根据前面算出来的 next 数组后移 ,直到匹配上。
有了 next 数组,KMP算法就很简单了
int KMP(string str1,string str2,int next[])
{
int i=0,j=0;
int l1=str1.length();//主串
int l2=str2.length();//模式串
while(i<l1)
{
if(str1[i]==str2[j])
{
i++;
j++;
}
else if(j==0)
{
i++;
}
else
{
j=next[j];
}
if(j>=l2)
{
return i-l2;//返回下标
}
}
return -1;//没有找到
}