传送门:http://poj.org/problem?id=3461
题目大意:给你两个字符串p和s,求出p在s中出现的次数。
题解:这一眼看过去就知道是KMP,作为模板来写是最好不过了。。。。
这道题我写了两种风格的kmp,个人感觉第2种好理解一些;
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #define inf 5 char s[1000100],p[100010]; 6 int next[100010]; 7 int lens,lenp,n; 8 using namespace std; 9 void getnext() 10 { 11 int j=-1,i=0; 12 next[0]=-1; 13 while (i!=lenp) 14 { 15 if (j==-1 || s[i]==s[j]) 16 next[++i]=++j; 17 else 18 j=next[j]; 19 } 20 } 21 int KMP() 22 { 23 int i=0,j=0,count=0; 24 while (i!=lens && j!=lenp) 25 { 26 if (s[i]==p[j]||j==-1) 27 ++i,++j; 28 else 29 j=next[j]; 30 if (j==lenp) 31 { 32 count++; 33 j=next[j]; 34 } 35 } 36 return count; 37 } 38 int main() 39 { 40 int z; 41 scanf("%d",&z); 42 for (int zz=1; zz<=z; zz++) 43 { 44 scanf("%s%s",p,s); 45 lens=strlen(s); 46 lenp=strlen(p); 47 //memset(next,0,sizeof(next)); 48 getnext(); 49 int ans=KMP(); 50 printf("%d ",ans); 51 } 52 }
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #define maxn 1000100 5 int n,fix,ans,i,lens,lent; 6 char s[maxn],t[maxn]; 7 int next[maxn]; 8 void getnext() 9 { 10 fix=0; 11 for (fix,i=2; i<=lent; i++) 12 { 13 while(fix && t[fix+1]!=t[i]) fix=next[fix]; 14 if (t[fix+1]==t[i]) fix++; 15 next[i]=fix; 16 } 17 } 18 int KMP() 19 { 20 int count; 21 fix=0; count=0; 22 for (int i=1; i<=lens; i++) 23 { 24 while (fix && t[fix+1]!=s[i]) fix=next[fix]; 25 if (t[fix+1]==s[i]) fix++; 26 if (fix==lent) 27 { 28 count++; 29 fix=next[fix]; 30 } 31 } 32 return count; 33 } 34 int main() 35 { 36 int z; 37 scanf("%d",&z); 38 for (int zz=1; zz<=z; zz++) 39 { 40 scanf("%s",t+1); 41 scanf("%s",s+1); 42 lens=strlen(s+1); lent=strlen(t+1); 43 memset(next,0,sizeof(next)); 44 getnext(); 45 ans=KMP(); 46 printf("%d ",ans); 47 } 48 }