模式串t 主串为s
#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<string.h>
using namespace std;
#define maxn 10005
char t[1005],s[maxn],n;
int f[maxn];
void getf()
{
int m=(int)strlen(t);
f[0]=f[1]=0;
for(int i=1;i<m;++i)
{
int j=f[i];
while(j&&t[i]!=t[j]) j=f[j];
f[i+1]= t[i]==t[j]?j+1:0;
}
}
void find()
{
int n,m;
n=(int)strlen(s);
m=(int)strlen(t);
getf();
int j=0;
for(int i=0;i<n;++i)
{
while(j&&t[j]!=s[i]) j=f[j];
if(t[j]==s[i]) j++;
if(j==m)
{
printf("%d %d\n",i,j);
printf("%d\n",i-m+1);
j=0;
}
}
}
int main()
{
scanf("%s%s",t,s);
find();
}
以上是白书上的思想
然后是自己的想法:
#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<string.h>
using namespace std;
char s[10005],t[1000010];
int f[1000010],n;
void getf()
{
f[0]=-1;f[1]=0;
int j=0,i=1;
while(i<n)
{
if(j==-1||t[i]==t[j])
{
j++;
i++;
f[i]=j;
}
else
{
j=f[j];
}
// if(j==-1){j=0;f[++i]=0;}
}
}
void kmp()
{
getf();
int m=(int)strlen(s);
for(int i=0;i<m;i++)
{
int j=0;
for(;j<n;j++)
{
if(s[i+j]!=t[j])
{
if(f[j]==-1){j=-1;break;}
else
{
i=j-f[j];
j=f[j];
}
}
}
if(j!=-1){printf("%d\n",i);}
}
}
int main()
{
memset(s,0,sizeof s);
memset(t,0,sizeof t);
scanf("%s%s",t,s);
n=(int)strlen(t);
kmp();
}