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