• 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函数返回值仍然是下标。

  • 相关阅读:
    JS中!=、==、!==、===的用法和区别
    Jquery判断Checkbox是否选中三种方法
    C# 信号量 学习
    redis学习资料
    Redis常用命令
    MySQL、HBase、ES的对比
    我对依赖注入,控制反转的理解
    net输出错误日志
    XmlExtensions帮助类
    DatetimeHelper类的编写
  • 原文地址:https://www.cnblogs.com/Asurudo/p/10493633.html
Copyright © 2020-2023  润新知