KMP字符串的模式匹配算法

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言


提示:以下是本篇文章正文内容,下面案例可供参考

一、KMP模式匹配算法

KMP模式匹配算法,是由三位科学家前辈(克努特-莫里斯-普拉特)发表,可以极大地避免重复遍历的情况,从而降低算法的时间复杂度
如果字符串非常长,不是依次性地调入内存,此情况更加适合KMP,为啥?因为KMP避免了不必要的回溯,而BF是需要回溯的,即回去找之前已经匹配过的字符。

二、C语言实现

#include<stdio.h>
void get_next(char* T, int *next){
	//  1 < i<= T[0]
	//求模式串T的next值,并放入next数组 
	int i = 1;int j = 0;next[1] = 0;		
	while (i <= T[0]){/*如果指针i在串的长度范围内,循环继续*/
		if (j==0 || T[i] == T[j]){/*T[i]为后缀的第i字符,T[j]为前缀的第j个字符
								  如果相等,则i下一位的next值next[i+1]=j+1*/
			i++;
			j++;
			next[i] = j;
		}
		else j = next[j];      /*不相等,则j回溯*/
	}
}//get_next

int index_kmp(char *S, char *T, int pos){
	// 1<=pos<=S的长度 
	int i = pos; /*pos是主串当前位置的下标值*/
	int j = 1;   /*j是模式串当前位置的下标值*/
	int next[255]; /*定义一个next数组*/
	get_next(T, next);/*得到模式串T的next数组*/
	while (i<=S[0] && j<=T[0]){ /*如果指针i小于主串S的长度且j小于模式串T的长度,
								即指针都在各自的范围内,则循环继续*/ 
		if (j==0 || S[i] == T[j]){/*若i所指的字符和j所指的字符相等,则继续比较后面的字符;
								  如果模式串的指针j回溯到0了,也继续比较下一位!*/
			++i;
			++j;
		}else 
		j = next[j];		     /*如果字符不相等,则j回溯;注意这里相比于BF算法,只是j回溯了,
		                         而i是没有回溯的,这样就避免了不必要的比较*/
	}
	if (j>T[0]){
		return i - T[0];
	}
	else return 0;	
}

//验证一下! 
int main(int argc, char const *argv[]){
	char T[] = " ababcababa";
	T[0] = 10;//首位存字符串T的长度 
	char S[] = " swap123ababcababassxyz";
	S[0] = 23;//同样首位存字符串S的长度 
	printf("T串在S串的%d处匹配成功!\n", index_kmp(S, T, 2));
	return 0;
}

结果:
在这里插入图片描述

三、总结

时间复杂度:
KMP:O(m+n)
BF:O((n-m+1)*m)最坏情况

例如:
S:0000 0000 0000 0001 m=16
T:0001 n=4
KMP: m+n=20 次!
BF:(16-4+1)*4=52 次

Obviously,KMP is better than BF!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

你抱着的是只熊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值