字符串查找-bf kmp

字符串可以通过bf和kmp方法查找  

bf 时间复杂度是O(n*m) 子串从头查找与串中原来与自己匹配的项如果匹配  就继续查找 如果 失配(不匹配)则返回到i(第一个匹配的字符)下一个(大概如下图)

《字符串查找-bf kmp》

优点 简单 缺点 时间复杂度比较大

代码如下

int BF(const char *str,const char *sub,int pos)//O(n*m)
{
	if(pos < 0)
	{
		return -1;
	}
	int lenstr = strlen(str);
	int lensub = strlen(sub);
	int i = pos;
	int j = 0;
	
	while(i<lenstr && j<lensub)
	{
		if(str[i] == sub[j])
		{
			i++;
			j++;
		}
		else
		{
			i = i-j+1;//失配,退到i原来的位置的下一个
			j = 0;
		}
	}

	if(j >= lensub)//找到了
	{
		return i-j;
	}
	else
	{
		return -1;
	}
}

KMP 优点:时间复杂度比较小O(n+m)缺点:比较复杂

要先知道子串的k和j  k==j  k和j是相等长度相等字符的两个字符串k从头开始找 j从子串失配前开始找

找k和j大概如下图

《字符串查找-bf kmp》

算法sub[j]==sub[k(j从1 开始j+1《lenstr k从0开始)]|| k=-1  k=k+1  继续

else k=next【k】继续

代码如下

static void GetNext(const char*sub,int *next)
{
	int lensub = strlen(sub);
	next[0] = -1;
	next[1] = 0;
	int j = 1;//通过j求j+1的值
	int k = 0;
	while(j+1<lensub)
	{
		if(k==-1 || sub[j]==sub[k])
		{
			next[++j] = ++k;//next[j]=k;++j;++k;
		}
		else
		{
			k = next[k];//
		}
	}

}

//KMP 算法特点:i不回退,时间复杂度O(n+m)
int KMP(const char *str,const char *sub,int pos)//O(n+m)
{
	if(pos < 0)
	{
		return -1;
	}
	int lenstr = strlen(str);
	int lensub = strlen(sub);
	int i = pos;
	int j = 0;
	int *next = (int *)malloc(lensub*sizeof(int));
	GetNext(sub,next);

	while(i<lenstr && j<lensub)
	{
		if(j==-1 || (str[i]==sub[j]))
		{
			i++;
			j++;
		}
		else//i不回退,j退到next[j](即k位置)
		{	
			j = next[j];
		}
	}

	free(next);

	if(j >= lensub)//找到了
	{
		return i-j;
	}
	else
	{
		return -1;
	}
}

KMP 获取next【i】(即k值)str[i]==sub[j])继续

else   子串的j退回之前k的位置 再继续

    原文作者:KMP算法
    原文地址: https://blog.csdn.net/LXY_liuxingyao/article/details/78147379
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞