KMP算法(模板)

       KMP算法用于字符串匹配,有两个字符串s,p,一个是文本串s,另一个是模式串p,现在要查找模式串p在文本串s中首次出现的位置是多少。暴力匹配的算法很容易想到,但是时间复杂度太高,运用KMP算法可以很好地解决这个问题。

       算法详解 从头到尾彻底理解KMP

//得到模式串p的next数组
void getnext(char *p,int *next){
    int lenp=strlen(p);
    next[0]=-1;
    int k=-1,j=0;
    while(j+1<lenp){
        if(-1==k || p[k]==p[j]){
            ++j;
            ++k;
            next[j]=k;
        }
        else k=next[k];
    }
}

//返回模式串p在文本串s中第一次出现的位置(从0下标开始),匹配失败则返回-1 
int kmp(char *s,char *p,int *next){
    int lens=strlen(s);
    int lenp=strlen(p);
    int i=0,j=0;
    while(i<lens && j<lenp){
        if(-1==j || s[i]==p[j]){
            ++i;
            ++j;
        }
        else j=next[j];
    }
    return j==lenp?i-j+1:-1;
}

       模板题 hdu 1711 稍有区别的是这道题不是字符串的匹配,而是整数序列的匹配,但思路和KMP算法是完全一样的

#include<cstdio>
using namespace std;

const int maxs=1000050;
const int maxp=10050;

int lens,lenp;
int s[maxs],p[maxp];
int next[maxp];

void getnext(){
    next[0]=-1;
    int k=-1,j=0;
    while(j+1<lenp){
        if(-1==k || p[k]==p[j]){
            ++j;
            ++k;
            next[j]=k;
        }
        else k=next[k];
    }
}

int kmp(){
    int i=0,j=0;
    while(i<lens && j<lenp){
        if(-1==j || s[i]==p[j]){
            ++i;
            ++j;
        }
        else j=next[j];
    }
    return j==lenp?i-j+1:-1;
}

int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        scanf("%d%d",&lens,&lenp);
        for(int i=0;i<lens;++i) scanf("%d",&s[i]);
        for(int i=0;i<lenp;++i) scanf("%d",&p[i]);
        getnext();
        int ans=kmp();
        printf("%d\n",ans);
    }
    return 0;
}
posted @ 2018-04-08 20:48  不想吃WA的咸鱼  阅读(119)  评论(0编辑  收藏  举报