KMP算法:一种用于字符串匹配的算法,精髓之处在于求next数组
模式串 | a | b | c | d | a | b | d | a | c |
下标 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
next数组 | 0 | 0 | 0 | 0 | 1 | 2 | 0 | 1 | 0 |
#include<cstdio>
#include<cstring>
const int N=75002;
char a[N],b[N];
int p[N],la,lb,first,last,ans1[N],ans2[N],tol1,tol2;
void KMP(char *S,char *T){
la=strlen(S+1);
lb=strlen(T+1);
int i,j;
for(j=p[1]=0,i=2;i<=la;i++){
while(j&&S[j+1]!=S[i])j=p[j];
if(S[j+1]==S[i])++j;
p[i]=j;
}
tol1=tol2=0;
first=last=-1;
for(j=0,i=1;i<=lb;i++){
while(j&&S[j+1]!=T[i])j=p[j];
if(S[j+1]==T[i])++j;
if(j==la&&first==-1)first=i-j;
//if(j==la)last=i-j,j=p[j];
//if(j==la)ans1[tol1++]=i-j,j=p[j];
//if(j==la)ans2[tol2++]=i-j,j=0;
}
}
int main(){
while(~scanf("%s%s",a+1,b+1)){
KMP(a,b);
printf("完全匹配的第一个位置:%d\n",first);
//printf("完全匹配的最后一个位置:%d\n",last);
//puts("字母可重复使用(从前往后)的所有匹配位置:");
//for(int i=0;i<tol1;i++)printf("%d ",ans1[i]);puts("");
//puts("字母不可重复使用(从前往后)的所有匹配位置:");
//for(int i=0;i<tol2;i++)printf("%d ",ans2[i]);puts("");
}
return 0;
}
/*
//测试数据
Input:
aba
dabaababacabdabadabaabd
Output:
完全匹配的第一个位置:1
完全匹配的最后一个位置:17
字母可重复使用(从前往后)的所有匹配位置:
1 4 6 13 17
字母不可重复使用(从前往后)的所有匹配位置:
1 4 13 17
*/