1. 程式人生 > 實用技巧 >KMP 洛谷 模板

KMP 洛谷 模板

  要掌握KMP ,重點掌握兩點 1.Next陣列的作用 2.Next陣列的求法。

#pragma warning(disable:4996)

#include<iostream>
#include<algorithm>
#include<bitset>
//#include<unordered_map>
#include<fstream>
#include<iomanip>
#include<string>
#include<cmath>
#include<cstring>
#include
<vector> #include<map> #include<set> #include<list> #include<queue> #include<stack> #include<sstream> #include<cstdio> #include<ctime> #include<cstdlib> #define INF 0x3f3f3f3f #define inf 0x7FFFFFFF #define MOD 1000000007 #define moD 1000000003 #define pii pair<int,int> #define
eps 1e-8 #define equals(a,b) (fabs(a-b)<eps) #define bug puts("bug") #define re register #define fi first #define se second const int maxn = 1e6 + 5; const double Inf = 10000.0; const double PI = acos(-1.0); typedef long long ll; using namespace std; char s1[maxn], s2[maxn]; int len1, len2; int Next[maxn];
void get_Next() { for (int i = 2, j = 0; i <= len2; i++) { while (s2[i] != s2[j + 1] && j > 0) j = Next[j]; if (s2[i] == s2[j + 1]) Next[i] = ++j; } } void kmp() { for (int i = 0, j = 0; i <= len1; i++) { while (s1[i] != s2[j + 1] && j > 0) j = Next[j]; if (s1[i] == s2[j + 1]) ++j; if (j == len2) { printf("%d\n", i - len2 + 1); j = Next[len2]; //如果全部匹配輸出,由於我們以及知道j的最大公共前後綴了,可以直接將j設為他的最大公共前後綴用以加速 } } } int main() { scanf("%s %s", s1 + 1, s2 + 1); len1 = strlen(s1 + 1), len2 = strlen(s2 + 1); get_Next(); kmp(); for (int i = 1; i <= len2; i++) printf("%d ", Next[i]); }