先上代码:
const int maxn=100010; //字符串长度最大值
int nt[maxn],ex[maxn]; //ex数组即为extend数组
///预处理计算next数组
void GETNEXT(char *str)
{
int i=0,j,po,len=strlen(str);
nt[0]=len;///用自己作为后缀与自己匹配
while(str[i]==str[i+1]&&i+1<len) i++;///暴力求next[1]
nt[1]=i;
po=1;///从此点出发next数组延伸位置最远
for(i=2;i<len;i++)
{
if(nt[i-po]< nt[po]+po-i )///第一种情况,可以直接得到next[i]的值
nt[i]=nt[i-po];
else///第二种情况,要继续匹配才能得到next[i]的值
{
j=nt[po]+po-i;
if(j<0)j=0; ///小于0表示没有已知相同部分,重新开始匹配
while(i+j<len&&str[j]==str[j+i])
j++;
nt[i]=j;
po=i;///更新po的位置
}
}
}
///计算extend数组
void EXKMP(char *s1,char *s2)
{
int i=0,j,po,len=strlen(s1),l2=strlen(s2);
GETNEXT(s2);
while(s1[i]==s2[i]&&i<l2&&i<len)
i++;
ex[0]=i;
po=0;
for(i=1;i<len;i++)
{
if(nt[i