KMP
1,n[ ]
for(j=1;j<strlen(p);j++)
{
//abababc 0
//不同时,k=4!=c
//k=n[4]=3!=c
//k=2!=c
//k=1!=c
//k=n[1]=0,<=0
while(k>0&&p[k]!=p[j])
k=n[k];
//开始k=0,和p0比较,相同则有一个相同
//a 0
//ab 0
//aba 1
//abab 2 有2个相同
//ababab 4
//abababc 0
if(p[k]==p[j])
k++;
n[j]=k;
}
2,kmp
for(i=0;i<strlen(t);i++)
{
//不匹配时,指针回退,但是会跳过前缀后缀相同的字符
while(k>0&&t[i]!=p[k])
{
printf("%c\n",t[i]);
//p[k]:c前面有n[k-1]个相同的,每个字符p[5]所在前面相同的是n[5]个
k=n[k-1];
}
if(t[i]==p[k])
k++;
if(k==strlen(p))
{
printf("Find \n");
return;
}
}
#include<stdio.h> #include<string.h> void next(char *p,int *n) { int j=0,k=0; n[0]=0; for(j=1;j<strlen(p);j++) { //abababc 0 //不同时,k=4!=c //k=n[4]=3!=c //k=2!=c //k=1!=c //k=n[1]=0,<=0 while(k>0&&p[k]!=p[j]) k=n[k]; //开始k=0,和p0比较,相同则有一个相同 //a 0 //ab 0 //aba 1 //abab 2 有2个相同 //ababab 4 //abababc 0 if(p[k]==p[j]) k++; n[j]=k; } } void kmp(char *t,char *p,int *n) { int i,k=0; //t:0-n for(i=0;i<strlen(t);i++) { //不匹配时,指针回退,但是会跳过前缀后缀相同的字符 while(k>0&&t[i]!=p[k]) { printf("%c\n",t[i]); //p[k]:c前面有n[k-1]个相同的,每个字符p[5]所在前面相同的是n[5]个 k=n[k-1]; } if(t[i]==p[k]) k++; if(k==strlen(p)) { printf("Find \n"); return; } } printf("Not find\n"); } int main() { int i; int n[7]; char p[8]="abababc",t[]="ababababc",s[]="abababdababddcc"; next(p,n); for(i=0;i<7;i++) printf("%d ",n[i]); printf("%d %d\n",strlen(p),strlen(t)); kmp(t,p,n); kmp(s,p,n); }