您的位置:首页 > 其它

kmp算法大全,历史详解

2016-03-14 20:17 176 查看
三种next数组推导:

(1)Poj-2752 前边字串等于最后字串

#include <stdio.h>

#include <string.h>

#include<iostream>

using namespace std;

int next[500000],a[500000];

char p[500000];

int i,j,k,len,t;

void naxt(int *next)

{

int i,j,k;

next[0]=-1;

j=0;

k=-1;

while(j<len)

{

if(k==-1||p[j]==p[k])

{

j++;

k++;

next[j]=k;

}

else

k=next[k];

}

}

int main()

{

while(scanf("%s",p)!=EOF)

{

memset(next,0,sizeof(next));

len=strlen(p);

naxt(next);

for(i=0; len!=0; i++)

{

a[i]=len;

len=next[len];

}

i--;

for(; i>=0; i--)

printf("%d ",a[i]);

printf("\n");

}

return 0;

}

(2)Poj-3461 字串在母串出现次数

#include <iostream>

#include<cstdio>

#include<algorithm>

#include<cstring>

#include<cmath>

using namespace std;

char T[1000000+100],P[10000+100];

int f[10000+100];

int cnt;//统计出现的次数

void find(char *T,char *P,int *f)

{

int n=strlen(T);

int m=strlen(P);

int j=0;

for(int i=0; i<n; i++)

{

if(j && T[i]!=P[j])

j=f[j];

if(T[i]==P[j])

j++;

if(j==m)

cnt++;

}

}

void getFail(char *P,int *f)

{

int m =strlen(P);

f[0]=f[1]=0;

for(int i=1; i<m; i++)

{

int j=f[i];

while(j && P[i]!=P[j])

j=f[j];

if(P[i]==P[j])

f[i+1] = j+1;

else

f[i+1]= 0;

}

}

int main()

{

int K;

scanf("%d",&K);

while(K--)

{

cnt=0;

scanf("%s %s",P,T);

getFail(P,f);

find(T,P,f);

printf("%d\n",cnt);

}

return 0;

}

(3)HDU-1711 子序列在母序列位置

#include<iostream>

#include<stdlib.h>

#include<stdio.h>

#include<string.h>

using namespace std;

const int p=1000005;

int ne[p],a[p];

int b[p],u,n,g,m;

void naxt()

{

ne[1]=0;

int i=1, j=0;

while(i<m)

{

if(j==0||b[i]==b[j])

{

++j;

++i;

if(b[i]!=b[j])

ne[i]=j;

else

ne[i]=ne[j];

}

else

j=ne[j];

}

}

int kmp()

{

int i=1;

int j=1;

while(i<=n&&j<=m)

{

if(j==0||a[i]==b[j])

{

++i;

++j;

}

else

{

j=ne[j];

}

}

if(j>m)

return i-m;

return 0 ;

}

int main()

{

scanf("%d",&u);

while(u--)

{

memset(ne,0,sizeof(ne));

memset(a,0,sizeof(a));

memset(b,0,sizeof(b));

scanf("%d%d",&n,&m);

for(int i=1; i<=n; i++)

scanf("%d",&a[i]);

for(int j=1; j<=m; j++)

scanf("%d",&b[j]);

naxt();

int o;

o=kmp();

if(o==0)

o=-1;

printf("%d\n",o);

}

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: