Loading

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]);
}

 

posted @ 2020-07-14 09:42  MQFLLY  阅读(189)  评论(0编辑  收藏  举报