KMP模板

来源:互联网 发布:nba球员数据统计 编辑:程序博客网 时间:2024/06/14 04:02

关于字符串的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+10000int 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;}




0 0
原创粉丝点击