首页 > 代码库 > KMP模板

KMP模板

关于字符串的AC自动机,KMP,Trie树,后缀数组。

KMP是基础。当一个字符串与模式串匹配的时,若失配,利用前面匹配的信息,利用三部分连等关系。可以滑动的“恰如其分”。

Next数组的求法:

若此时求的是next[i]的数值,j位置之前的与从i开始后j-1个字符都是匹配的,若s[i]==s[j] 那么next[++i]=++j; 若不相等可以j=next[j]滑动回去。

OK,那么什么时候匹配串滑动?我们设定next[0]=-1,当一直回溯到0还不匹配就滑动吧。

发一道模板题 HDU 1686

#include<algorithm>
#include<iostream>
#include<iterator>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<map>
#define inf (1<<30)
#define mem(a) memset(a,0,sizeof(a))
using namespace std;
typedef long long ll;
const int maxn=10+100;

int N,M;
#define N 30+10000

int next[N];
void getNext(char *s)
{
    int i = 0, j = -1;
    next[0] = -1;
    int len=strlen(s);
    while(i != len)
    {
        if(j == -1 || s[i] == s[j])
        {
            ++i,++j;
            if(s[i]!=s[j])
                next[i] =j;
            else
                next[i]=next[j];
        }
        else
            j = next[j];
    }
}
int KMP(char *s1, char *s2)
{
    int i=0,j=0;
    int len1=strlen(s1),len2=strlen(s2);
    int res=0;
    while(i<len2)
    {

        if(j==-1 || s1[j]==s2[i])
            i++,j++;
        else
            j=next[j];
        if(j==len1)
            res++,j=next[j];
    }
    return res;
}
char s1[11000],s2[1100000];
int main()
{
    int T;
    scanf("%d",&T);
    getchar();
    while(T--){
        gets(s1);gets(s2);
        getNext(s1);
        printf("%d\n",KMP(s1,s2));
    }
    return 0;
}




KMP模板