KMP算法-找出模式串匹配标准串的第一个位置

KMP算法-找出字串出现的第一个位置

我们先得出子串(也就是标准串的NEXT[]表的值。上讲已经讲过如何算出给定子串的NEXT[]表的值,此讲不再冗述。

第一步给出算NEXT[]表值的算法

arr[]为题目给出的标准串,brr[]是给定要寻找位置的子串。
next[]是我们新开辟的数组为空,等待我们算出值放入。

void GETNEXT(char brr[], char next[])
{
	int j=0, k=-1;
	next[0] = -1;
	while(j < strlen(brr)-1)
	{
		if(brr[j]==brr[k] || k==-1)
		{
			j++;
			k++;
			next[j] = k;
		}
		else k = next[k];
	}
}

第二步开始找

先给出代码
arr[]为题目给出的标准串,brr[]是给定要寻找位置的子串。
next[]是我们新开辟的数组为空,等待我们算出值放入。

char next[];
int KMPIndex(char arr[], char brr[])
{
	GETNEXT(brr, next);
	int i=0, j=0;
	while(i < strlen(arr) && j < strlen(brr) //当标准串没有扫完,并且模式串也没有扫完
	{
		if(j==-1 || arr[i)==brr[j])
		{
			i++;
			j++;
		}
		else j = next[j];
	} 
	//两方若有一方先扫完,或都扫完
	if(j >= strlen(brr)//匹配成功
		return i-strlen(brr);
	else return -1;
}

给大家举个栗子

给定标准串 a a a a b
给定模式串 a a a b
显然模式串的NEXT[]表的值为

j 0 1 2 3
brr [ ] a a a b
next [ ] -1 0 1 2
i=0, j=0时

‘a’ = ‘a’
arr[0] == brr[0] ,所以i++, j++

i=1, j=1时

‘a’ = ‘a’
arr[1] == brr[1] , 所以i++, j++

i=2, j=2时

‘a’ = ‘a’
arr[2] == brr[2] , 所以i++, j++

i=3, j=3时

‘a’ != ‘b’
所以 j=next[j]=next[3]=2; i不变

i=3, j=2时

‘a’ = ‘a’
arr[3] == brr[2] , 所以i++, j++

i=4, j=3时

‘b’ = ‘b’
arr[4] == brr[3] , 所以i++, j++

因为i >= strlen(arr),循环结束
并且j >= strlen(brr) 说明找到啦

返回子串第一次出现的位置 i-strlen(brr)
就是现在 i 代表的位置是标准串中‘b’的位置,我们减去子串的长度,就是子串第一次出现的位置

我们可以发现当子串与标准串不同的时候(我们记当前标准串的字母为arr[index] );子串会整体移动;移动到子串从后往前看,子串第一次和arr[index]相等的位置。 我们会发现移动后的子串还是会和标准串相匹配。next表工作就是这个 这需要读者自己理解一下。
发布了17 篇原创文章 · 获赞 7 · 访问量 931

猜你喜欢

转载自blog.csdn.net/weixin_43898134/article/details/103055493
今日推荐