首页 > 其他 > 详细

KMP 算法

时间:2014-04-04 09:16:07      阅读:411      评论:0      收藏:0      [点我收藏+]

KMP 算法 与 朴素算法相比少了不必要的重复工作,比如ABABCD串在C处失配应从第二个A处匹配,不是第一个A处匹配。所以KMP的关键是状态转移表(预处理时间是0(M)),总的时间复杂度是0(M + N)。

状态转移就是模式串每个位置的最大相等子串。

前提:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
char w[10010];
char t[1000010];
int next[10010];
int cnt;

解释状态转移表:

void get_next()
{
	next[0] = 0;
	next[1] = 0;
	int j ;
	for(int i = 1; w[i]!= ‘\0‘; i ++)
	{
		j = next[i]; 
		while(j && w[j] != w[i]) j = next[j];
		next[i+1] = w[j] == w[i] ? j + 1: 0;
	}
}

0 , 1 的最大相等子串为长度为0.求状态转移是递推的过程,由next[i]推出next[i+1].已得到模式串在i处的最大相等子串长度L(0 ,1,2,。。L-1),如果w[i] == w[j](w[i] == w[L])

则next[i+1] = L+1(0 ,1,2,3,....,L),如果w[i] != w[j](w[i] != w[L]),最大相等子 串为0,next[i+1] = 0;

匹配过程:

void kmp()
{
	int j = 0 , m = strlen(w); 
	for(int i = 0; t[i] != ‘\0‘; i ++)
	{
		while(j && w[j] != t[i]) j = next[j];
		if(w[j] == t[i]) j ++;
		if(j == m) cnt ++;
	}
}

完整代码:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
char w[10010];
char t[1000010];
int next[10010];
int cnt;
void get_next()
{
	next[0] = 0;
	next[1] = 0;
	int j ;
	for(int i = 1; w[i]!= ‘\0‘; i ++)
	{
		j = next[i]; 
		while(j && w[j] != w[i]) j = next[j];
		next[i+1] = w[j] == w[i] ? j + 1: 0;
	}
}

void kmp()
{
	int j = 0 , m = strlen(w); 
	for(int i = 0; t[i] != ‘\0‘; i ++)
	{
		while(j && w[j] != t[i]) j = next[j];
		if(w[j] == t[i]) j ++;
		if(j == m) cnt ++;
	}
}
int main()
{
	int n ;
	scanf("%d",&n);
	while(n --)
	{
		scanf("%s",w);
		nex();
		cnt = 0;
		scanf("%s",t);
		kmp();
		cout << cnt << endl;
	}
	return 0;
}



KMP 算法,布布扣,bubuko.com

KMP 算法

原文:http://blog.csdn.net/wuhuajunbao/article/details/22900491

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!