码迷,mamicode.com
首页 > 其他好文 > 详细

KMP专题

时间:2017-08-22 00:21:19      阅读:131      评论:0      收藏:0      [点我收藏+]

标签:string   class   return   using   main   names   click   gif   isp   

1、HDU 1711 Number Sequence

  题意:给出两个数字串a,b,问能否使得数字串b为a的子串,能输出最小的匹配位置。

  思路:KMP模板题

技术分享
 1 #include<iostream>
 2 #include<cstring>
 3 using namespace std;
 4 const int maxn = 1000010;
 5 const int maxm = 10010;
 6 int p[maxm];
 7 int des[maxn];
 8 int Next[maxm];
 9 int n, m;
10 void GetNext(int *next, int *src, int len)
11 {//next和src都从下标1开始存储
12     next[1] = 0;
13     int j = 1, i = 0;
14     while (j <= len)
15     {
16         if (i == 0 || src[j] == src[i])
17         {
18             j++;
19             i++;
20             next[j] = i;
21         }
22         else i = next[i];
23     }
24 }
25 
26 int KMP(int *T, int *P, int *next)//在目标串T中从位置1开始查找模式串P第一次出现的位置
27 {
28     int lenT = n;
29     int lenP = m;
30     int posT = 1, posP = 1;
31     while (posP <= lenP&&posT <= lenT)
32     {
33         if (posP == 0 || T[posT] == P[posP])
34         {
35             ++posT;
36             ++posP;
37         }
38         else posP = next[posP];
39     }
40     if (posP <= lenP) return -1;
41     else return posT - lenP;
42 }
43 int main()
44 {
45     int t;
46     scanf("%d", &t);
47 
48     while (t--)
49     {
50         scanf("%d%d", &n, &m);
51         for (int i = 1; i <= n; i++) scanf("%d", &des[i]);
52         for (int i = 1; i <= m; i++) scanf("%d", &p[i]);
53         GetNext(Next, p, m);
54         printf("%d\n", KMP(des, p, Next));
55     }
56     return 0;
57 }
View Code

2、HDU 1686 Oulipo

  题意:给出模式串p,文本串t,求p在t中出现的次数(可重叠)

  思路:KMP同时记录匹配的个数。

技术分享
 1 #include<iostream>
 2 #include<cstring>
 3 using namespace std;
 4 const int maxn = 1000100;
 5 const int maxp = 10010;
 6 char t[maxn];
 7 char p[maxp];
 8 int Next[maxp];
 9 void GetNext(int *next, char *src, int len)
10 {//next和src都从下标0开始存储
11     next[0] = -1;
12     int j = 0, i = -1;
13     while (j < len)
14     {
15         if (i == -1 || src[j] == src[i])
16         {
17             j++;
18             i++;
19             next[j] = i;
20         }
21         else i = next[i];
22     }
23 }
24 
25 int KMP(char*T, char *P, int *next)//在目标串T中从位置1开始查找模式串P第一次出现的位置
26 {
27     int lenT = strlen(T);
28     int lenP = strlen(P);
29     int posT = 0, posP = 0;
30     int cnt = 0;
31     while (posT <lenT)
32     {
33         if (posP == -1 || T[posT] == P[posP])
34         {
35             ++posT;
36             ++posP;
37         }
38         else posP = next[posP];
39         if (posP== lenP)
40         {
41             cnt++;
42             posP = next[posP];
43         }
44     }
45     return cnt;
46 }
47 int main()
48 {
49     int Case;
50     scanf("%d", &Case);
51     while (Case--)
52     {
53         scanf("%s", p);
54         scanf("%s", t);
55         GetNext(Next, p, strlen(p));
56         printf("%d\n", KMP(t,p, Next));
57     }
58     return 0;
59 }
View Code

3、hdu 2087 剪花布条

  题意:给出a串和b串,求b串在a串中出现的次数(不可重叠)

  思路:KMP。注意更新指针时和上一题的不同。

技术分享
 1 #include<iostream>
 2 #include<cstring>
 3 using namespace std;
 4 const int maxn = 1010;
 5 const int maxp = 1010;
 6 char t[maxn];
 7 char p[maxp];
 8 int Next[maxp];
 9 void GetNext(int *next, char *src, int len)
10 {//next和src都从下标0开始存储
11     next[0] = -1;
12     int j = 0, i = -1;
13     while (j < len)
14     {
15         if (i == -1 || src[j] == src[i])
16         {
17             j++;
18             i++;
19             next[j] = i;
20         }
21         else i = next[i];
22     }
23 }
24 
25 int KMP(char*T, char *P, int *next)//在目标串T中从位置1开始查找模式串P第一次出现的位置
26 {
27     int lenT = strlen(T);
28     int lenP = strlen(P);
29     int posT = 0, posP = 0;
30     int cnt = 0;
31     while (posT <lenT)
32     {
33         if (posP == -1 || T[posT] == P[posP])
34         {
35             ++posT;
36             ++posP;
37         }
38         else posP = next[posP];
39         if (posP == lenP)
40         {
41             cnt++;
42             posP++;
43         }
44     }
45     return cnt;
46 }
47 int main()
48 {
49     while (~scanf("%s",&t))
50     {
51         if (t[0] == #)break;
52         scanf("%s", p);
53         GetNext(Next, p, strlen(p));
54         printf("%d\n", KMP(t, p, Next));
55     }
56     return 0;
57 }
View Code

 

KMP专题

标签:string   class   return   using   main   names   click   gif   isp   

原文地址:http://www.cnblogs.com/ivan-count/p/7407228.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!