BF算法、KMP算法、改进的KMP算法

BF算法、KMP算法、改进的KMP算法,以上几种算法都是模式匹配算法,即找模式串在主串中第一次出现的位置。

BF算法:

BF算法、KMP算法、改进的KMP算法_第1张图片

如上图所示 主串:”abcaba”   子串:”aba”

思路:从主串第一个开始和子串第一个匹配,如果相等则两个串都向后走一步,继续匹配。如果不相等则主串从i-j+1开始、子串从头开始重新匹配。可以看到每当失配时,主串的i需要从开始匹配的下一个字符开始,重新和子串开始匹配。即每次失配了就执行 i=i-j+1,j=0操作。整个时间复杂度O(n*m)。n表示主串长度、m表示子串长度。

代码:

int BF(const char* s,const char* sub,int pos)
{
	int i=pos;
	int j=0;
	int lens=strlen(s);
	int lensub=strlen(sub);
	while(i=lensub)
	{
		return i-j;
	}
	return -1;
}

KMP算法的实现:

思路:主串的i不回退,子串的j也只回退到指定的位置,而不用每次都会退到0。因为有些回退是没有必要的。而具体j回退到哪个位置,就需要我们写next数组了。

next数组存在的意义:不用将j回退到0,而是回退到next数组的值

BF算法、KMP算法、改进的KMP算法_第2张图片

代码:

void GetNext(int* next,const char* sub)
{
	int lensub=strlen(sub);
	next[0]=-1;
	next[1]=0;

	int i=2;//开始从第3位,下标为2的开始,是匹配该位之前的
	int k=0;
	while(i=lensub)
	{
		return i-j;
	}
	return -1;
}

改进的KMP算法:

BF算法、KMP算法、改进的KMP算法_第3张图片

nextval代码:

void GetNextVal(int* nextval,const char* sub)
{
	int lensub=strlen(sub);
	nextval[0]=-1;
	int i=0;
	int k=-1;
	while(i

 

下面我们来整体测试一些代码

int main()
{
	const char* s="abcaabbcabcaabdab";
	const char* sub="abbc";
	cout<

运行结果:

为查看next数组和nextval数组添加一个打印函数

void Print(int *arr,int len)
{
	for(int i=0;i

现在来看一下两个数组的结果:

int main()
{
	const char* s="abcaabbcabcaabdab";
	const char* sub="aaaaaaaab";
	int lensub=strlen(sub);
	int lens=strlen(s);
	int* next=(int*)malloc(sizeof(int)*lens);
	int* nextval=(int*)malloc(sizeof(int)*lens);
	GetNext(next,sub);
	GetNextVal(nextval,sub);
	Print(next,lensub);
	Print(nextval,lensub);
	GetNext(next,s);
	GetNextVal(nextval,s);
	Print(next,lens);
	Print(nextval,lens);
	return 0;
}

结果:

BF算法、KMP算法、改进的KMP算法_第4张图片

和我们想的一样。但是有些书上起始是从0开始而不是从-1开始,这样的话我们还是按这种方法计算next数组,然后将数组的每个值都加1就好了。

你可能感兴趣的:(数据结构)