随着对它的记忆加深,对KMP的模板做法也有所感触,类型是一样的,做法也是模板做法,处理的也只是细节问题而已,其实也就是这些细节是需要想的、处理的,不然就是一题了,上篇要求是看是否有子串,如果有返回此子串在另一数串的最先开始的位置,这题与上题要求不同,能出现的次数,而且只要不是同一位置的情况下都算(看了题,应该可以明白这个意思的),不过我感觉应该好处理的,就是i变化是处理妥当就行;
题目链接: http://poj.org/problem?id=3461
代码如下:
#include<stdio.h>
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include<string.h>
2 int len1,len2;
3 char str1[10001];
4 char str2[1000001];
5 int next[10001];
6 void index_next()
7 {
8 int i,j;
9 next[0]=-1;
10 j=-1;
11 for(i=1;i<len1;i++)
12 {
13 while(j>-1&&str1[i]!=str1[j+1])
14 j=next[j];
15 if(str1[i]==str1[j+1])
16 j++;
17 next[i]=j;
18 }
19 }
20 int kmp()
21 {
22 int i,j,sum;
23 j=-1;
24 sum=0;
25 for(i=0;i<len2;i++)
26 {
27 while(j>-1&&str2[i]!=str1[j+1])
28 j=next[j];
29 if(str2[i]==str1[j+1])
30 j++;
31 if(j==len1-1)//与上题不同之处就在这里
32 {
33 sum++;
34 j=next[j];
35 }
36 /*if(j==len1-1)//用这个屏蔽的会超时的,答案应该不错,效率不高
37 {
38 sum++;
39 i=i-j+1;
40 j=-1;
41 }*/
42 }
43 return sum;
44 }
45 int main()
46 {
47 int t,d;
48 scanf("%d",&t);
49 getchar();
50 while(t--)
51 {
52 gets(str1);
53 gets(str2);
54 len1=strlen(str1);
55 len2=strlen(str2);
56 index_next();
57 d=kmp();
58 printf("%d\n",d);
59 }
60 return 0;
61 }