KMP&&e-KMP

KMP

KMP是一种快速的字符串匹配算法,关键步骤是对每一个匹配串产生一个next数组。

void kmp_next(char *s)
{
    int len = strlen(s);
    next[0] = -1;
    int k = -1;
    for(int i = 1; i < len; i ++) {
        while(k > -1 && s[k+1] != s[i]) {
            k = next[k];
        }
        if(s[k+1] == s[i]) {
            k ++;
        }
        next[i] = k;
    }
}

Number Sequence

HDU - 1711

#include
#include
#include
#include
using namespace std;
const int MAXM=10500;
const int MAXN=1000500;
int n,m,t;
int nextc[MAXM];
int ori[MAXN];
int des[MAXM];
void findnext(){
    int k=-1,j=0;
    while(j

e-KMP

算法链接:https://subetter.com/algorith...

扩展KMP算法:给定两个字符串S和T(长度分别为n和m),下标从0开始,定义extend[i]等于S[i]...S[n-1]与T的最长相同前缀的长度,求出所有的extend[i]。
为获得extend数组,我们首先要构造一个辅助数组next,next[i]代表T[i:]和T[:]的最长公共子前缀。

/* 求解 T 中 next[],注释参考 GetExtend() */
void GetNext(string & T, int & m, int next[])
{
    int a = 0, p = 0;
    next[0] = m;

    for (int i = 1; i < m; i++)
    {
        if (i >= p || i + next[i - a] >= p)
        {
            if (i >= p)
                p = i;

            while (p < m && T[p] == T[p - i])
                p++;

            next[i] = p - i;
            a = i;
        }
        else
            next[i] = next[i - a];
    }
}

/* 求解 extend[] */
void GetExtend(string & S, int & n, string & T, int & m, int extend[], int next[])
{
    int a = 0, p = 0;
    GetNext(T, m, next);

    for (int i = 0; i < n; i++)
    {
        if (i >= p || i + next[i - a] >= p) // i >= p 的作用:举个典型例子,S 和 T 无一字符相同
        {
            if (i >= p)
                p = i;

            while (p < n && p - i < m && S[p] == T[p - i])
                p++;

            extend[i] = p - i;
            a = i;
        }
        else
            extend[i] = next[i - a];
    }
}

Simpsons’ Hidden Talents

HDU - 2594
本题既可以使用KMP又可以使用扩展KMP算法。
算法一:扩展KMP

//eKMP
#include
#include
#include
using namespace std;
const int MAXN=50050;
const int MAXM=50050;
int n,m;
char o[MAXN];
char d[MAXM];
int nexts[MAXM];
int extend[MAXN];
void getNext(){
    int i=0,p=m,a=0;//p是之前所能匹配的最大位置,[a,p)是当前最大匹配,现在开始匹配i
    nexts[0]=m;
    if(m<1)
        return;
    p=1;
    while(p=p||i+nexts[i-a]>=p)
        {
            if(i>=p)
            p=i;
            while(d[p]==d[p-i])
                p++;
            nexts[i]=p-i;
            a=i;
        }else{
            nexts[i]=nexts[i-a];
        }
    }
}
void getExtend(){
    int a = 0, p = 0;
    getNext();

    for (int i = 0; i < n; i++)
    {
        if (i >= p || i + nexts[i - a] >= p) // i >= p 的作用:举个典型例子,S 和 T 无一字符相同
        {
            if (i >= p)
                p = i;

            while (p < n && p - i < m && o[p] == d[p - i])
                p++;

            extend[i] = p - i;
            a = i;
        }
        else
            extend[i] = nexts[i - a];
    }
}
int main(){
    while(~scanf("%s%s",&d,&o)){
        memset(nexts,0,sizeof(nexts));
        memset(extend,0,sizeof(extend));
        n=strlen(o);
        m=strlen(d);
        getExtend();
        int ans=0;
        for(int i=0;i

算法二:KMP

//KMP
#include
#include
#include
using namespace std;
const int MAXN=50050;
const int MAXM=50050;
int nexts[MAXN+MAXM];
char S[MAXN+MAXM];
char s1[MAXM];
int n;
void getNext(){
    int k=-1,i=0;
    nexts[i]=-1;
    for(int i=1;i=0&&S[i]!=S[k+1])
                k=nexts[k];
            if(S[i]==S[k+1])
                k=k+1;

        }
        nexts[i]=k;
    }
}
int main(){
    while(~scanf("%s%s",&S,&s1)){
        strcat(S,"*");
        strcat(S,s1);
        n=strlen(S);
        getNext();
        int ans=nexts[n-1];
        if(ans==-1)
            printf("0\n");
        else{
            for(int i=0;i<=ans;i++){
                printf("%c",S[i]);
            }
            printf(" %d\n",ans+1);
        }
    }
}

你可能感兴趣的:(KMP&&e-KMP)