KMP算法详解

数据结构-KMP算法(C语言版)
KMP算法简介:
KMP算法是三位学者在 BF算法的基础上同时提出的模式匹配的改进算法。
BF算法在模式串中有多个字符和主串中的若干个连续字符比较都相等,但最后一个字符比较不相等时,主串的比较位置需要回退。KMP算法在上述情况下,主串位置不需要回退,从而可以大大提高效率.

难点:
理解KMP算法的难点即在于其中的求next数组,而求next数组的难点即在于其中的j回溯操作 也就是 j=next[j] 很多同学难以理解这个操作。

个人方法:
这里我们要理解 j=next[j] 这一回溯操作 就要回归next数组的定义 。
next数组:在模式匹配串T失配时,next数组对应的元素指导应该用T串的哪个元素进行下一轮的匹配
举例:
模式串T a b a b a a a b a
下标 0 1 2 3 4 5 6 7 8
next数组 -1 0 0 1 2 3 1 2 3
当i=5 j=3时. T[3]!= T[5] 回溯 j=next[j] 再进行比较
为什么是 j=next[j]呢?根据上面next数组的定义 在j处失配则通过next[j]指定j的新值进行下次匹配 即是j=next[j]

代码如下:

#include<stdio.h>
#include<stdlib.h> 
#include<string.h>
//这个获取next数组的函数有些难以理解,如果你能搞懂这个函数,KMP算法基本就理解了
void GetNext(char *T,int *next,int lenth){
	//设置初始值 
		next[0]=-1;
		int i=0;
		int j=-1;
	//循环 当i<数组长度时 
	while(i<lenth){
		if(j==-1||T[i]==T[j]){//当j=-1:表示第i+1项的前缀和后缀没有一个相等的
							  //当T[i]==T[j] 表示此时前后缀相等 
			i++;
			j++;
			next[i]=j; 
		}
		else{//当此时的前缀和后缀不相等时0
			j=next[j];//j回溯 指向新的前缀 
		}
	}
}
int KMP(char S[],char T[]){
	int next[20];
	int i=0,j=0;
	int lenS=strlen(S);
	int lenT=strlen(T);
	GetNext(T,next,lenT);
	while(i<lenS&&j<lenT){
		if(j==-1||S[i]==T[j]){
			i++;
			j++;
		}
		else{
			j=next[j];//这里的next数组会有些难以理解
		}
	}
	if(j==lenT){
		return (i-j);
	}
	else{
		return -1;
	}
}


int main()
{
	int k;
	char s[100];
	char t[100]; 
	printf("请输入主串\n") ;
	gets(s);
	printf("请输入模型串\n");
	gets(t);
	//调用KMP算法
	k=KMP(s,t);
	if(k==-1){
		printf("主串中未找到与模型串匹配的子串\n");
	}
	else{
		printf("在主串第%d个字符后找到与模型串匹配的子串\n",k);
	}
	return 0;
}

若有更好的建议或者有什么不足欢迎评论区指出!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值