码迷,mamicode.com
首页 > 编程语言 > 详细

kmp算法

时间:2019-02-27 01:25:12      阅读:210      评论:0      收藏:0      [点我收藏+]

标签:long   lan   amp   double   blog   art   数组   字符串   ace   

https://blog.csdn.net/dl962454/article/details/79910744

https://blog.csdn.net/qq_40938077/article/details/80460853

https://blog.csdn.net/liujiuxiaoshitou/article/details/70232219

 

https://vjudge.net/contest/240809#problem/A习题链接

Number Sequence

 HDU - 1711 

//这道题的next数组是由优化的next数组写的,next数组的含义不是指最长前缀与后缀的长度,因为加了递归优化,值一般就是-1与0.
//求最开始的匹配位置。(题目意思)
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxm = 1e6 + 5; int a[maxm], b[maxm], nex[maxm]; int t, n, m, x; void getnext() { nex[0] = -1; int k = -1; int j = 0 ; while(j < m - 1) { if(k == -1 || b[j] == b[k]) { j++, k++; if(b[j] != b[k]) nex[j] = k; else nex[j] = nex[k]; } else k = nex[k]; } } int kmps() { int i = 0, j = 0; getnext(); while(i < n && j < m) { if(j == -1 || a[i] == b[j]) { i++, j++; } else j = nex[j]; // printf("cbuisdc\n"); } if(j == m) return i - j + 1; return -1; } int main() { scanf("%d", &t); while(t--) { scanf("%d%d", &n, &m); for(int i = 0; i < n; i++) { scanf("%d", &a[i]); } for(int i = 0; i < m; i++) { scanf("%d", &b[i]); } if(kmps() == -1) printf("-1\n"); else printf("%d\n", kmps()); } return 0; }

Period

 HDU - 1358 

技术图片

从这一题把next数组输出可知,next数组值该字符串的最长相同前缀与后缀,而且是包含了本身的。(如果这么说的话,相当于把字符串下标从1开始)

//这个是没加递归优化的next数组,指的是最长前缀与后缀的值。
//题目意思是指在i之前的字符串是不是有循环节的,有的话就输出循环节的长度与循环节的个数。
#include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int maxm = 1e6 + 5; int n; int nex[maxm]; void getnext(char ch[], int m) { memset(nex, 0, sizeof(nex)); nex[0] = -1; int j = 0, k = -1; while(j < m) { if(k == -1 || ch[j] == ch[k]) { j++; k++; nex[j] = k; } else k = nex[k]; } //for(int i = 0; i <= m; i++) { // printf("%d \n", nex[i]); //} //printf("\n"); } char ch[maxm]; int main() { int cnt = 0; while(~scanf("%d", &n) && n) { scanf("%s", ch); getnext(ch, n); printf("Test case #%d\n", ++cnt); for(int i = 2; i <= n; i++) { int j = i - nex[i]; if(j != i) { if(i % j == 0) { printf("%d %d\n", i, i / j); } } } printf("\n"); } return 0; }

 Simpsons’ Hidden Talents

 HDU - 2594 

//这个nex数组是用的最长前缀与后缀,题目意思是指求两个字符串的最长相同的前缀与后缀。
//这个在kmp匹配那里有不同,重点看一下。还有一种做法是直接把两个字符串拼接起来,在中间加一个特殊字符,然后在用kmp去求最长前缀与后缀的长度。

/*
@Author: Top_Spirit @Language: C++ */ //#include <bits/stdc++.h> #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std ; typedef unsigned long long ull ; typedef long long ll ; const int Maxn = 5e4 + 10 ; const int INF = 0x3f3f3f3f ; const double PI = acos(-1.0) ; const ull seed = 133 ; string s1, s2 ; int len1, len2 ; int Next[Maxn] ; void getNext(){ Next[0] = -1 ; int j =0, k = -1 ; while (j < len1 ){ if (k == -1 || s1[j] == s1[k]) Next[++j] = ++k ; else k = Next[k] ; } } void KMP (){ int i = 0, j = 0 ; while (i < len2){ if (j == -1 || s1[j] == s2[i]){ i++ ; j++ ; } else j = Next[j] ; } if (j){ for (int k = 0; k < j; k++) cout << s1[k] ; cout << " " << j << endl ; } else cout << 0 << endl ; } int main (){ while (cin >> s1 >> s2 ){ len1 = s1.size() ; len2 = s2.size() ; getNext() ; KMP() ; } return 0 ; }

 

kmp算法

标签:long   lan   amp   double   blog   art   数组   字符串   ace   

原文地址:https://www.cnblogs.com/downrainsun/p/10441172.html

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