KMP算法之我见

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

int* next(const char* cpPartten,int iParttenSize);
int kmp(const char* cpTarget,const char* cpPartten);

void main()
{
	char* cpTarget=NULL;
	char* cpPartten=NULL;
	int answer=0;
	cpTarget=malloc(200);
	cpPartten=malloc(20);
	printf("Target:");
	scanf("%s",cpTarget);
	fflush(stdin);
	printf("Partten:");
	scanf("%s",cpPartten);
	answer=kmp(cpTarget,cpPartten);
	free(cpTarget);
	free(cpPartten);
}

int* next(const char* cpPartten,int iParttenSize)
{
	//准备工作
	int i=0,j=0;
	int* iNext=NULL;
	if(iParttenSize<1)
		return iNext;//error
	iNext=malloc(sizeof(int)*iParttenSize);
	
	//易知
	iNext[0]=-1;
	if(iParttenSize!=1)
		if(cpPartten[0]==cpPartten[1])
			iNext[1]=-1;
		else
			iNext[1]=0;

	//分情况讨论
	i=1;
	j=iNext[i];
	while(i<iParttenSize-1)
	{
		if(cpPartten[j]==cpPartten[i])
		{
			iNext[i+1]=iNext[i]+1;
		}
		else
		{
			j=iNext[j];
			if(j==-1)
				iNext[i+1]=0;
			else
				continue;
		}
		i++;
		j=iNext[i];
		if(cpPartten[j]==cpPartten[i])
			iNext[i]=iNext[j];
	}
	return iNext;
}

int kmp(const char* cpTarget,const char* cpPartten)
{
	int iTargetSize=0,iParttenSize=0,i=0,j=0;
	int* iNext=NULL;
	
	iTargetSize=strlen(cpTarget);
	iParttenSize=strlen(cpPartten);
	iNext=next(cpPartten,iParttenSize);
	if(iNext==NULL)
		return -2;//error

	while(iTargetSize>=iParttenSize && i<=iTargetSize)
	{
		if(cpTarget[i]==cpPartten[j])
		{
			if(j==iParttenSize-1)
				return i-(iParttenSize-1);
			i++;
			j++;
		}
		else
		{
			if(iNext[j]==-1)
			{
				i++;
				j=0;
				continue;
			}
			j=iNext[j];
		}
	}
	free(iNext);
	return -1;//no matching
}

感觉高中学的数学真心是有作用的,它教会我们处理问题。先易后难,这是化难为易的好方法。

建议初学KMP算法的同学(因人而异,自选对有用的,我的不一定适合你):

1、对于用惯C的同学,不要看到讲解时从1开始对串编号而感觉不舒服。先懂过程,最后最后的结果不过是把你学的结果-1而已。

2、书上不一定能看懂,上网上找找答案。网上很多都是讲自己认识的过程,这很有帮助。

3、一时半会看不懂先放下,没准过一会灵光一闪就懂了呢,但不要放弃。

我就不说我怎么懂这玩意儿了,网上有很多。

参考:KMP算法详解 - joylnwang的专栏 - 博客频道 - CSDN.NET

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值