• ACM模板——KMP


    #include <bits/stdc++.h>
    using namespace std;
    
    #define pb push_back
    #define _for(i,a,b) for(int i = (a);i < (b);i ++)
    const int maxn = 50003; 
    
    int fail[maxn];
    void makefail(char *t,int lt)
    {
        --t;
        for(int i = 1,j = 0;i <= lt;i ++,j ++)
        {
            fail[i] = j;
            while(j>0 && t[i]!=t[j]) j = fail[j];
        }
    }
    
    //match pattern T in S
    int kmp(char *s,int ls,char *t,int lt,int i,int &longest,int &lp)
    {
        longest = lp = 0;--s;--t;
        for(int j = 1;i <= ls;i ++,j ++)
        {
            while(j>0 && s[i]!=t[j]) j = fail[j];
            if(j>longest) {longest = j;lp = i-j;}
            if(j==lt) return i-lt;
        }
        return -1;
    }
    
    int main()
    {
        char s[100] = "ababaaaaaaab";
        char t[100] = "babababa";
        
        int ls = strlen(s),lt = strlen(t);
        int longest,lp;
        makefail(t,lt);
        _for(i,0,lt)
            cout << fail[i] << " ";
        cout << endl;
        cout << kmp(s,ls,t,lt,4,longest,lp) << endl;
        cout << longest << " " << lp << endl;
        return 0;
    }
    KMP

    makefail()函数就是打next数组,调用KMP函数之前一定记得要先调用一遍makefail()

    s是待匹配串,而t是模式串,ls和lt就是各自的长度,i是从下标为i+1处开始进行匹配,longest是所能匹配到的最长t的子串或其本身开始的位置,lp是所能匹配到的最长t的子串或其本身的长度

    需要注意以上所说的i和longest的位置,都是字符在匹配串中的下标位置加一,即正常理解的第几个字符,而不是匹配串下标!但kmp函数返回值仍然是下标。

  • 相关阅读:
    python IDE比较与推荐
    一个平庸程序员的想法
    [转载]Malcolm的新书:Outliers
    程序员的编辑器——VIM
    Blender网络资源
    普通人的编辑利器——Vim
    易学易用的Windows PowerShell
    分区表的修复(转)
    云南电信DNS服务器地址
    滇南本草(上)
  • 原文地址:https://www.cnblogs.com/Asurudo/p/10493633.html
Copyright © 2020-2023  润新知