KMP 入门
以下面数据为例子
13 5
a[] = 1 2 1 2 3 1 2 3 1 3 2 1 2
b[] = 1 2 3 1 3
(1)构造next表
b[] = 1 2 3 1 3
next[] = 0 0 0 1 0
(2)匹配a[]
i = 1 2 3 4 5 6 7 8 9 10 11 12 13
a[] = 1 2 1 2 3 1 2 3 1 3 2 1 2
j = 1 2 1 2 3 4 2 3 4 5
b[] = 1 2 3 1 3
b[] = 1 2 3 1 3
b[] = 1 2 3 1 3
#include <stdio.h>
#include <string.h>
/*
2
13 5
1 2 1 2 3 1 2 3 1 3 2 1 2
1 2 3 1 3
13 5
1 2 1 2 3 1 2 3 1 3 2 1 2
1 2 3 2 1
*/
const int N = 1000005;
const int M = 10005;
int a[N];
int b[M],next[M];
int n,m;
void getNext()
{//建立next 表,根据b数组
int j=0;
next[1]=0;
for(int i=2;i<=m;i++)
{
while(j>0 && b[i]!= b[j+1])
j=next[j];
if(b[i] == b[j+1])
j++;
next[i]=j;
}
/*
for(int i=1;i<=m;i++)
printf("%d ",next[i]);
printf("\n");*/
}
int kmp()
{
int j=0;int ans=0;
for(int i=1;i<=n;i++)
{
//匹配失败,跳转next
while(j>0 && a[i]!=b[j+1])
j=next[j];
//继续向下匹配
if(a[i]==b[j+1])
j++;
//与b数组匹配成功的数量恰好为b数组长度
if(j==m)
return i-m+1;
}
return -1;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=1;i<=m;i++)
scanf("%d",&b[i]);
getNext();
printf("%d\n",kmp());
}
return 0;
}
本文详细介绍KMP算法的工作原理及其实现过程,通过具体实例演示如何构造next表,并使用该表进行字符串匹配。文章还提供了完整的C语言代码实现。
4011

被折叠的 条评论
为什么被折叠?



