KMP
注意:Fail[1]=0(代码中的字符数组下标从1开始)
Fail数组有两个性质:
①有关循环节:对于一个长度为Len的字符串,它的循环节长度是Len-Fail[Len](数组下标从1开始);如果Len%(Len-Fail[Len])!=0,就没有循环节。
②有关树:如果把所有的Fail值连上边,那么所构成的图是一棵树。
代码
void kmp()
{
//建立Fail[]
//i:主串中的前i-1位已经被讨论过,当前讨论第i位
//j:模式串中的前j位已经被匹配了,当前匹配第j+1位
//匹配主串中的第i位和模式串中的第j+1位
Fail[1]=j=0;
for(i=2;i<=m;i++)
{
while(j>0&&B[j+1]!=B[i])j=Fail[j];
if(B[j+1]==B[i]) j++;
Fail[i]=j;
}
// 寻找匹配的位置
j=0;
for(i=1;i<=n;i++)
{
while(j>0 && B[j+1]!=A[i])j=Fail[j];
if(B[j+1]==A[i]) j++;
if(j==m)
{ cout<<"match: "<<i-m+1<<endl; j=Fail[j]; }
}
}