KMP算法的next数组最简单粗暴的掌握

“KMP算法”,又称看毛片算法(我瞎说的),这个算法的引入极大地优化了字符串匹配的匹配的效率。是一个十分著名的算法。
它的原理就是通过给要匹配的字符串加一个next数组,以这个数组来作为它的回溯指导,减去不必要的回溯。那么首先来看一下next数组的规则是什么,我简单概括一下,就是判断当前位置的后缀有无前缀匹配,如果有,假设后缀字符串长度为n,为多少就在当前位置填n+1;
举个简单的例子,字符串T和它的next数组;

T          a b a a b a a b
next       0 1 1 2 2 3 4 2

首先要明确前缀必须从第一位开始它是固定的,不能从第二位开始。
我们分析第一个,next[1]始终是0,这个不解释,然后从第二位开始肯定也是1这是固定的,
然后我们从3位看起,这时候,前缀的值为a,后缀是b,不匹配填1,
第4位,前缀依旧是a,后缀变成a,有匹配值长度1,填1+1;
第5位,后缀虽然有aa,但是没有前缀匹配,故只能是后缀a和a匹配,填2;
第6位,前缀可以ab了,后缀也是ab,匹配,长度2,填2+1;
第7位,后缀aba可以找到匹配的前缀值,长度为3,填3+1;
这就是比较简单的理解,如果你是应付考试,做题看到这里就可以结束了,下面要说的是真正的难以理解的地方。我们来看一段代码,可以跟着代码单步调试理解,

void get_next(String T, int *next)
{
	int i = 1;
	int j = 0;
	next[1] = 0;
	while (i < T[0])
	{
		if (0==j || T[i] == T[j])//匹配失败就回溯,成功给next[]赋值;
		{
			i++;
			j++; 
			if (T[i] != T[j]) 
			{ next[i] = j; }//把数组位置给next[i];
			else
				next[i] = next[j];
		}
		else {
			j = next[j];//回溯位,
		}
	}
}
int KMP(String S,String T)
{
	int i = 1;
	int j = 1;
	int next[255];
	get_next(T, next);
	while (i <= S[0] && j <= T[0])
	{
		if (0 == j || S[i] == T[j])
		{
			i++;
			j++;
		}
		else
		{
			j = next[j];//从回溯位置开始继续匹配
		}
	}
	if (j > T[0])
	{
		return i - T[0];
	}
	else
	{
		printf("查找失败");
		return 0;
	}
}
void main()
{
	char S[255] = " ababaaaba";
	S[0] = 9;
	
	char T[255]=" abc";
	T[0] = 3;
	printf("%d", KMP(S, T));
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值