First of all, I recommend a kmp spoken by an Indian brother: easy to understand
Website: https://www.bilibili.com/video/av3246487
We directly use a sample question: http://acm.sdut.edu.cn/onlinejudge2/index.php/Home/Contest/contestproblem/cid/2710/pid/2772
Basically, this topic is considered as a new knowledge point. Take it over and review it (note: my next array corresponds to one, not the previous number, please be careful)
#include<stdio.h>
#include<string.h>
char str1[1000010],str2[1000010];
int next[1000010];
void makenext(char str2[],int next[])//Get the substring next array
{ int i,k,m; m=strlen(str2); k=0; next[0]=0; for(i=1;i<m;i++)//The first substring does not need to be considered { if(k>0&&str2[i]!=str2[k])//Does not conform to { k=next[k-1]; In fact, the process of constructing next is also a kmp process, if you encounter inequality, you must skip to the front Front } if(str2[i]==str2[k])//Conform { k++; } next[i]=k; } } void kmp(char str1[],char str2[],int next[]) {
int i,k,m,n,flag=0;
m=strlen(str2);//substring length
n=strlen(str1);//main string length
makenext(str2,next);
k=0;
for( i=0;i<n;i++)//i traverse the main string
{ if(k>0&&str1[i]!=str2[k])//2. If the first few matches in the matching process, the last one suddenly fails If it matches, it will return to the one after the matched prefix { k=next[k-1]; } if(str1[i]==str2[k])//1. When a matching letter appears k++ { k++ ; } if(k==m) { flag=1; printf("%d\n",i-m+2); } } if(flag==0) { printf("-1\n"); } }
int main()
{
while(scanf("%s %s",str1,str2)!=EOF)
{
kmp(str1,str2,next);
}
return 0;
}