C语言KMP算法的实现

        KMP算法在需要大量元素进行对比的时候比BF算法更为快速。注意,接下来的串都是以下标为1作为起始储存位置。

下面说一下实现代码:

        首先是函数头、预定义和类型定义:

#define MAXLEN 100

typedef struct{
	char ch[MAXLEN + 1];
	int length;
}SString;

KMP算法主体函数:

int Index_KMP(SString S, SString T, int pos)
{
	int i, j;
	int next[MAXLEN + 1];
	i = pos;
	j = 1;
	get_next(T, next);
	while (i < S.length&&j < T.length)
	{
		if (j == 0 || S.ch[i] == T.ch[j])
		{
			++i;
			++j;
		}
		else
			j = next[j];
	}
	if (j >= T.length)
		return i - T.length + 1;
	else
		return 0;
}

     先对模式串T的next[]进行取值,具体实现函数get_next()下面给出。将pos的值赋值给i,表示从元素的第pos个值开始对比;让j等于1,表示模式串T从第一个元素开始对比。当j等于0的时候,表示之前没有任何元素相同,且此时i和j都在下一轮该对比的元素的前一位,所以让i和j均加1。当i小于S.length并且j小于T.length的时候,将S.ch[i]和T.ch[j]进行对比,若相等,则对比下一位元素,若不相等,则让j回到模式串T开头和模式串T的j之前匹配的位置。最后当跳出循环的时候,若j的值大于或等于T.length的话,则说明匹配成功,返回该位置;否则表示匹配失败,返回0.

    接下来是对结构串的next[]进行取值的函数get_next():

void get_next(SString T, int next[])
{
	int i, j;
	next[1] = 0;
	i = 0;
	j = 1;
	while (j < T.length)
	{
		if (i == 0 || T.ch[i] == T.ch[j])
		{
			++i;
			++j;
			next[j] = i;
		}
		else
			i = next[i];
	}
}

        在看这段代码之前,先理解next[i]的值。个人理解,next[i]记录着开头与当前位置前一位元素匹配的元素的位置。让next[1]=0,在对比过程中,当存在不相等的情况的时候,若此时i=1,则i会等于0,此时模式串T的i,j都在对比元素的前一位,则让i,j都加1,并且让T中下标j的位置指向位置标记为1,回到第一位元素。

        加入main()进行测试:


int callen(SString S)
{
	int i;
	for (i = 0; S.ch[i] != '\n'; i++);
	return i;
}

int main(void)
{
	SString S, T;
	int pos = 1, n, i;
	for (i = 1; S.ch[i - 1] != '\n'; i++)
	{
		S.ch[i] = getchar();
	}
	S.length = callen(S);
	fflush(stdin);
	for (i = 1; T.ch[i - 1] != '\n'; i++)
	{
		T.ch[i] = getchar();
	}
	T.length = callen(T);
	n = Index_KMP(S, T, pos);
	printf("%d\n", n);
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值