zoukankan      html  css  js  c++  java
  • 模板汇总——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], " 
    "[i==n+m]);
        }
        return 0;
    }
    int main(){
        Ac();
        return 0;
    }
    View Code

      

  • 相关阅读:
    class-决策树Decision Tree
    class-朴素贝叶斯NaiveBayes
    class-k近邻算法kNN
    [linux环境配置]个人用持续更新ing~
    [python基础] python生成wordcloud并保存
    [算法基础]快排、归并、堆排序比较
    [算法基础]斐波那契(recursion+loop)两种方式执行时间对比
    [python基础]xml_rpc远程调控supervisor节点进程
    [Supervisor]supervisor监管gunicorn启动DjangoWeb时异常退出
    [python基础] csv.wirterow()报错UnicodeEncodeError
  • 原文地址:https://www.cnblogs.com/MingSD/p/10802603.html
Copyright © 2011-2022 走看看