模板汇总——KMP & EX-KMP

1. kmp

  相当于往前求出一段字符信息,使得 这段字符信息和前缀相等。

   

void getnext(){
    int k = -1, j = 0;
    nx[0] = -1;
    while(j < m){
        if(k == -1 || b[j] == b[k]) nx[++j] = ++k;
        else k = nx[k];
    }
}
View Code

例:

T

#include<iostream>
using namespace std;
int nx[10000+5], b[10000+5], a[1000000+5];
int n, m;
void getnext(){
    int k = -1, j = 0;
    nx[0] = -1;
    while(j < m){
        if(k == -1 || b[j] == b[k]) nx[++j] = ++k;
        else k = nx[k];
    }
}
int KMP()
{
    int flag = -1;
    for(int i = 0, j = 0; i < n; i++){
        while(j > 0 && b[j] != a[i]) j = nx[j];
        if(a[i] == b[j]) j++;
        if(j == m)
        {
            return i - j + 2;
        }
    }
    return -1;
}
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin >> t;
    while(t--){
        cin >> n >> m;
        for(int i = 0; i < n; i++) cin >> a[i];
        for(int i = 0; i < m; i++) cin >> b[i];
        getnext();
        cout << KMP() << endl;
    }
    return 0;
}
View Code

2. ex-kmp 

  相当于往后求出一段信息,使得这段信息和前缀相等。

int n, z[N];
char s[N];
void init(){
    z[0] = n;
    int j = 1, k;
    for(int i = 1; i < n; i = k){
        if(j < i) j = i;
        while(j < n && S[j] == S[j-i]) j++;
        z[i] = j-i;
        k = i+1;
        while(k + z[k-i] < j)
            z[k]=z[k-i],k++;
    }
}
View Code

例:

T:

给出模板串A和子串B,长度分别为lenA和lenB,要求在线性时间内,对于每个A[i](1<=i<=lenA),求出A[i..lenA]与B的最长公共前缀长度。

#include<bits/stdc++.h>
using namespace std;
const int N = 2e6+100;

char s[N], ss[N];
int z[N];
void init(int n){
    z[0] = n;
    int j = 1, k;
    for(int i = 1; i < n; i = k){
        if(j < i) j = i;
        while(j < n && s[j] == s[j-i]) j++;
        z[i] = j-i;
        k = i+1;
        while(k + z[k-i] < j)
            z[k]=z[k-i],k++;
    }
}
int Ac(){
    scanf("%s", ss);
    scanf("%s", s);
    int n = strlen(s), m = strlen(ss);
    s[n] = '@';
    strcpy(s+1+n, ss);
    init(n+m+1);
    for(int i = n+1; i <= n+m; ++i){
        printf("%d%c", z[i], " \n"[i==n+m]);
    }
    return 0;
}
int main(){
    Ac();
    return 0;
}
View Code

  

猜你喜欢

转载自www.cnblogs.com/MingSD/p/10802603.html
今日推荐