输入
第一行一个整数N,表示测试数据组数。
接下来的N*2行,每两行表示一个测试数据。在每一个测试数据中,第一行为模式串,由不超过10^4个大写字母组成,第二行为原串,由不超过10^6个大写字母组成。
其中N<=20
输出
对于每一个测试数据,按照它们在输入中出现的顺序输出一行Ans,表示模式串在原串中出现的次数。
- 样例输入
-
5 HA HAHAHA WQN WQN ADA ADADADA BABABB BABABABABABABABABB DAD ADDAADAADDAAADAAD
- 样例输出
-
3 1 3 1 0
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 5 #define N 20 6 #define TNum 1000005 7 #define PNum 10005 8 9 void KMP_Matcher(char pattern[][PNum], char terget[][TNum], int); 10 int *getNext(char pattern[], int); 11 12 int main( int argc, char* argv[] ) 13 { 14 int num, i; 15 char pattern[N][PNum]; 16 char terget[N][TNum]; 17 18 scanf("%d", &num); 19 for (i = 0; i < num; i++) 20 { 21 scanf("%s", pattern[i]); 22 scanf("%s", terget[i]); 23 } 24 25 KMP_Matcher(pattern, terget, num); 26 27 system("pause"); 28 return 0; 29 } 30 31 32 void KMP_Matcher(char pattern[][PNum], char terget[][TNum], int num) 33 { 34 int i; 35 long int numOfMatcher; 36 for (i = 0; i < num; i++) 37 { 38 int j; 39 int n, m, q; 40 int *next; 41 42 m = strlen(pattern[i]); 43 n = strlen(terget[i]); 44 q = -1; 45 numOfMatcher = 0; 46 47 next = getNext(pattern[i], m); 48 // printf("%d %d ", next[0], next[1]); 49 50 for (j = 0; j < n; j++) 51 { 52 while(q > -1 && pattern[i][q + 1] != terget[i][j]) 53 { 54 q = next[q]; 55 } 56 if (pattern[i][q + 1] == terget[i][j]) 57 { 58 q++; 59 } 60 if (q == m - 1) 61 { 62 numOfMatcher++; 63 q = next[q]; 64 } 65 } 66 printf("%ld ", numOfMatcher); 67 free(next); 68 } 69 } 70 71 72 int *getNext(char pattern[], int m) 73 { 74 int k,q; 75 int *next; 76 next = (int *)malloc(m * sizeof(int)); 77 78 next[0] = -1; 79 k = -1; 80 81 for (q = 1; q < m; q++) 82 { 83 while(k > -1 && pattern[k + 1] != pattern[q]) 84 { 85 k = next[k]; 86 } 87 if (pattern[k + 1] == pattern[q]) 88 { 89 k++; 90 } 91 next[q] = k; 92 } 93 94 return next; 95 }
KMP主要内容是求解前缀函数,详解见《算法导论》