KMP专题

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 }

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 }

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 }

时间: 2024-10-11 14:27:06

KMP专题的相关文章

KMP专题总结

KMP算法有两种计算失配函数的方法 未优化过的失配函数 , f[i] 就表示 str[0~i-1] 的公共最长前后缀( 不包括str[0~i-1]本身,比如aaa的最长公共前后缀长度为2 ) , 这个特性必须牢记 从下面的例子应该也可以看出 0  1  2  3  4  5  6  7  8  9  10 str  a  a  a  a  b  b  a  a  b  a  '\0' f   0  0  1  2  3  0  0  1  2  0   1 优化过后的失配函数,虽然匹配的性能要好

2017-4-13:KMP专题

G - 剪花布条(KMP) 一块花布条,里面有些图案,另有一块直接可用的小饰条,里面也有一些图案.对于给定的花布条和小饰条,计算一下能从花布条中尽可能剪出几块小饰条来呢? Input 输入中含有一些数据,分别是成对出现的花布条和小饰条,其布条都是用可见ASCII字符表示的,可见的ASCII字符有多少个,布条的花纹也有多少种花样.花纹条和小饰条不会超过1000个字符长.如果遇见#字符,则不再进行工作. Output 输出能从花纹布中剪出的最多小饰条个数,如果一块都没有,那就老老实实输出0,每个结果

hdu---2087---剪花布条

hdu2087剪花布条字符串的处理 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2087 这题水的不要不要的,各种数据都能过,醉醉的 写他的目的是在KMP专题上随时都要充实自己,又长知识了. kmp算法完成的任务是:给定两个字符串O和f,长度分别为n和m,判断f是否在O中出现,如果出现则返回出现的位置. 常规方法是遍历a的每一个位置,然后从该位置开始和b进行匹配,但是这种方法的 复杂度是O(nm).kmp算法通过一个O(m)的预处理,使匹配的复杂

大一下学期以来做题总结、

这段时间以来.除了搜索专题和KMP专题 其他专题都不怎么愿意想了. 就比如今天的水题. 代码敲错. 输出格式没看清题意. 看题又不仔细. 等交上去错一发之后在回过头来看题目. 而且看题这方面真的好差. 经常性题目没读完就开始去敲代码.在敲代码过程中再去看题意. 希望自己读题的时候要认真.争取把题目读准.读快. 还有一个坏习惯.做题的时候喜欢听歌.这样在做思维题的时候多少会有点影响把. 这样好了,以后在做题时间一定一定不要听歌. 还有就是思维方面比以前欠缺一点了. 可能是因为没有比赛时的感觉的了.

E - Period HDU-1358

题目大意: 多组.给一个n,输入长度为n 的串,求:这个串所有存在循环节的前缀,输出前缀长度和循环次数(不重叠). 解题思路: 从i=0开始,判断前缀是不是存在循环节,即(i+1)%(i-next[i]) 是否==0 .注:next[i]值是0或-1的忽略,说明前面不存在任何循环节.(关于循环节解释的见<KMP 专题知识>). 参考代码: 1 #include <iostream> 2 #include <stdio.h> 3 using namespace std;

D - Cyclic Nacklace HDU-3746

题目大意: 给一个t,接下来每个t,给一个串,求出最小循环节下还要增加多少个珠子才完美.(要是都没啥循环节,就输出长度) 解题思路: 求出最小循环节 cir:cir=len - next[len] (关于为什么是这个式子详见<KMP 专题知识>),然后拿len%cir得到的余数就是已经有的,那么拿循环节再减掉有的,就是需要增加的.即:cir-len%cir.如果len%cir == 0,而且cir!=len,就意味着一颗都不用增加,因为此时已经是完美的循环了,但是要是cir==len,就说明没

(字典树)How many--hdu--2609

http://acm.hdu.edu.cn/showproblem.php?pid=2609 How many Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1707    Accepted Submission(s): 693 Problem Description Give you n ( n < 10000) necklaces

KMP &amp; 扩展KMP &amp; Manacher 专题

KMP & 扩展KMP & Manacher  专题 先来模版: void getNext(int *b,int m) { Next[0]=-1; int i=0,j=-1; while(i<m&&j<m){ if(j==-1||b[i]==b[j]) Next[++i]=++j; else j=Next[j]; } } int kmp(int *a,int *b,int n,int m) { getNext(b,m); int i=0,j=0; while(i

·专题」 KMP

KMP 总结 1.strstr函数 |函数名: strstr |功 能: 在串中查找指定字符串的第一次出现 |用 法: char *strstr(char *str1, char *str2); |据说strstr和KMP的算法效率差不多|注意:返回的是该字符串第一次出现时的指针,所以如果要计算下标,可以用原字符串首地址-返回的地址. 因为这样,还可以直接输出余下的字符串 1 int main() 2 { 3 char T[] = {"I love you ,do you know?"