在字符串中不可重叠地寻找子串数量,暴力/KMP

 1 #include<stdio.h>
 2 #include<string.h>
 3 
 4 int main(){
 5     char a[1005],b[1005];
 6     while(scanf("%s",a)!=EOF&&a[0]!='#'){
 7         scanf("%s",b);
 8         getchar();
 9         int la=strlen(a),lb=strlen(b);
10         int ans=0,i,j,p=0;
11         for (i=0,j=0;i<la;i++,j++){
12             if(j==1) p=i;
13             if (a[i]!=b[j]) {
14                 if(j!=0) i=p-1;
15                 j=-1;
16             }
17             else {
18                 if (j==lb-1) {
19                     ans++;
20                     j=-1;
21                 }
22             }
23         }
24         printf ("%d\n",ans);
25     }
26     return 0;
27 }
View Code
 1 #include<stdio.h>
 2 #include<string.h>
 3 
 4 const int maxn=1e3+5;
 5 const int maxm=1e3+5;
 6 
 7 char s[maxn],t[maxm];    //s为待匹配串,t为模板串
 8 int p[maxm];    //自匹配数组
 9 
10 int main(){
11     while(scanf("%s",s)!=EOF&&s[0]!='#'){    //这个是字符串从下标0开始的
12         scanf("%s",t);
13         int i,j,ans=0;    //ans记录字符串出现次数
14         int n=strlen(s),m=strlen(t);    //在题目中遇到过,其实strlen很慢,所以如果不先存起来可能有TLE的风险
15         p[0]=p[1]=0;    //初始化自匹配数组
16         for(i=1;i<m;i++){    //自匹配
17             j=p[i];
18             while(j&&t[i]!=t[j])j=p[j];
19             p[i+1]=t[i]==t[j]?j+1:0;
20         }
21         j=0;            //注意 j=0
22         for(i=0;i<n;i++){    //串匹配
23             while(j&&s[i]!=t[j])j=p[j];
24             if(s[i]==t[j])j++;
25             if(j==m){
26                 ans++;        //此处记录出现次数(模板串在待匹配串中可重叠),或改为直接break表示是否出现过
27                 j=0;
28             }
29         }
30         printf("%d\n",ans);
31     }
32     return 0;
33 }
View Code