23.字符串匹配,KMP算法

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<assert.h>

//BF算法(一般思路的字符串匹配)
int BF(const char *s, const char *sub, int pos)  //pos表示从s的pos位置处开始匹配
{
	int i = pos;
	int j = 0;
	int lens = strlen(s);
	int lensub = strlen(sub);

	while ((i < lens) && (j < lensub))
	{
		if (s[i] == sub[j])
		{
			i++;
			j++;
		}
		else
		{
			i = i - j + 1;  //匹配失败,i回到开始匹配位置+1的下标处,j=0
			j = 0;
		}
	}

	if (j >= lensub)
	{
		return i - j;
	}
	else
	{
		return -1;
	}
}

//KMP算法
void GetNext(int *next, const char *sub)
{
	int lensub = strlen(sub);
	next[0] = -1;
	next[1] = 0;
	int i = 2;
	int k = 0;

	while (i < lensub)
	{
		if ((k == -1) || (sub[i - 1] == sub[k]))
		{
			//next[i] = k + 1;
			//i++;
			//k += 1;
			next[i++] = ++k;
		}
		else
		{
			k = next[k];  //不是k = next[i],因为是在k位置处出现失配
		}
	}

	//对next数组进行优化,当发生不匹配且next[j]元素与当前j下标元素相同,直接跳过,减少不必要的匹配
	for (int j = 1; j < lensub; j++)
	{
		if (sub[next[j]] == sub[j])
		{
			next[j] = next[next[j]];
		}
	}
}

int KMP(const char *s, const char *sub, int pos)
{
	int i = pos;
	int j = 0;
	int lens = strlen(s);
	int lensub = strlen(sub);
	int *next = (int*)malloc(lensub * sizeof(int));
	assert(next != NULL);

	GetNext(next, sub);  //得到sub的next数组

	while (i < lens && j < lensub)
	{
		if ((j == -1) || (s[i] == sub[j]))
		{
			i++;
			j++;
		}
		else
		{
			j = next[j];	//匹配不相等时只改变j下标,i不用回退	
		}
	}

	free(next);

	if (j >= lensub)
	{
		return i - j;
	}
	else
	{
		return -1;
	}
}

int main()
{
	char *s = "abcabababcabd";
	char *sub = "abcabd";

	//int pos = BF(s, sub, 0);
	int pos = KMP(s, sub, 0);
	printf("%d\n", pos);

	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值