POJ 3461
一道KMP算法的基础题,用于熟悉KMP算法和求next数组,关于KMP算法,为自己写了一篇总结。
这道题要注意的是,模式串可以重叠,比如给出ACA与ACACACA,应该出现了3次,这里只需要在KMP的函数里稍微改动一下即可:如果模式串的位置等于了模式串的长度,说明模式串已经被完整地匹配了,并且,此时模式串的位置由于等于了长度,所以这里是并没有字符的,但next值会存在(详情见求next数组的值的函数),此时只需要假设它们不匹配,转到此时的next值即可。
#include<stdio.h> #include<string.h> #define MAX_WORD 10005 #define MAX_TEX 1000005 char s[MAX_TEX],p[MAX_WORD]; int next[MAX_WORD],ans; void get_next(void); void kmp(void); int main() { int n; scanf("%d",&n); while(n--) { scanf("%s",p); scanf("%s",s); ans=0; kmp(); printf("%d\n",ans); } return 0; } void kmp(void) { int lenP=strlen(p),lenS=strlen(s),i,posP=0,posS=0; for(i=0;i<=lenP;i++) { next[i]=0; } get_next(); while(posS<lenS) { if(posP==-1||p[posP]==s[posS]) { posP++;posS++; if(posP==lenP) { ans++; posP=next[posP]; } } else { posP=next[posP]; } } } void get_next(void) { int i=0,j=-1,len=strlen(p); next[0]=-1; while(i<len) { if(j==-1||p[i]==p[j]) { i++;//如果i=len-1,执行这步会使next[len]存在 j++; next[i]=j; } else { j=next[j]; } } }