KMP入门 博客推荐+模板+入门习题

KMP入门

入门介绍

KMP入门博客推荐

next数组讲解

模板代码

//这个是对next进行的优化
void getnext()               //做的第一步是获得next【】的值
{
	int i=0,k=-1;
	next[0]=-1;
	while(i<lenb)
	{
		if(k==-1 || str[i]==str[k])
        {
            i++; k++;
            if(t[i]==t[k])
                next[i]=next[k];
           	else next[i]=k;
        }
		else k=next[k];
	}
}
//没有带优化的部分
void getnext()               //做的第一步是获得next【】的值
{
	int i=0,k=-1;
	next[0]=-1;
	while(i<lenb)
	{
		if (k==-1 || b[i]==b[k])
			next[++i]=++k;
		else k=next[k];
	}
}
int KMP()
{
	getnext();
	int i=0,j=0,cnt=0;
	while (i<lena)
	{
		if (j==-1||a[i]==b[j])
		{
			i++;j++;
		}
		else j=next[j];
		if (j==lenb)
		{
            cnt++; //记录一共有多少个匹配的字符串
			printf("%d
", i-j+1); //输出匹配的位置,从1开始的。
			j=next[j];//接下来继续匹配
		}	
	}
    return cnt;
}

完整的代码,这个代码对应的题目为洛谷P3375

#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=1e6+7;
char a[maxn],b[maxn];
int next[maxn];
int lena, lenb;
void getnext()               //做的第一步是获得next【】的值
{
	int i=0,k=-1;
	next[0]=-1;
	while(i<lenb)
	{
		if (k==-1 || b[i]==b[k])
			next[++i]=++k;
		else k=next[k];
	}
}
void KMP()
{
	getnext();
	int i=0,j=0,cnt=0;
	while (i<lena)
	{
		if (j==-1||a[i]==b[j])
		{
			i++;j++;
		}
		else j=next[j];
		if (j==lenb)
		{
			printf("%d
", i-j+1);
			j=next[j];
		}	
	}	
}
int main()
{
	while(scanf("%s",a)!=EOF)
	{
		scanf("%s",b);
		lena=strlen(a);
		lenb=strlen(b);
		KMP();
		for(int i=1; i<=lenb; i++)//这里是从1开始的,而不是从0开始,因为next数组中第一个位置的-1
            //实际上只是个界限,没有其他作用,实际next数组是从1开始的。
		{
			printf("%d ", next[i]);
		}
		printf("
");
	}
	return 0;
}
欢迎评论交流!
原文地址:https://www.cnblogs.com/alking1001/p/12243172.html