KMP算法

输入

第一行一个整数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\n", 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\n", 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主要内容是求解前缀函数,详解见《算法导论》



posted @ 2014-10-28 15:46  yyxayz  阅读(355)  评论(0编辑  收藏  举报