KMP算法

KMP算法的核心是求解next数组。
首先要理解next数组的含义。
next[i]包含s[i]之前的子串(即s[0…i-1],不包含s[i])最长公共前后缀的信息。其值表示公共前后缀前缀的最后一位下标
next数组的作用是指示模式串pattern失配后应该退回的位置,因此在做题的时候,要根据字符串的下标是从0开始还是从1开始来判断整体是否要加上1。
next数组可以优化为nexval数组,进一步减小时间复杂度。
nextval数组表示pattern失配时的最佳回退位置
求解next的核心:

s[i]==s[next[j]+1]? next[i] = next[j] + 1 : next[i] = j (循环本句);

求解next数组

// getNext求解长度为len的字符串s的next数组
void getNext(char s[],int len)
{
	int j = -1;
	next[0] = -1;//初始化j=next[0] = -1 
	for(int i = 1;i < len;i++)//求解next[1] ~ next[len - 1] 
	{
		while(j != -1 && s[i] != s[j+1])
		{
			j = next[j];//反复令j = next[j] 
		}
		if(s[i] == s[j + 1])//如果s[i] == s[j+1] 
		{
			j++;//则next[i] = j + 1,先令j指向这个位置 
		}
		next[i] = j;//令next[i]  = j
	}
 } 

判断是否是子串

//KMP算法,判断pattern是否是text的子串
 bool KMP(char text[],char pattern[])
 {
 	int n = strlen(text),m = strlen(pattern);//字符串长度
	getNext(pattern,m);//计算pattern的next数组
	int j = -1;//初始化j为-1,表示当前还没有任意一位被匹配 
	for(int i = 0;i < n; i++)//试图匹配text[i] 
	{
		while(j != -1 && text[i] != pattern[j+1])
		{
			j = next[j];//不断回退,直到j回到-1或text[i] = pattern[j + 1] 
		}
		if(text[i] == pattern[j + 1])
		{
			j++;//text[i] 与pattern[j+1] 匹配成功,令j加1 
		}
		if(j == m -1)//pattern完全匹配,说明pattern是text的子串 
		{
			return true;
		} 
	 } 
	 return false;	//执行完text还没匹配成功,说明pattern不是text的子串 
 } 

统计pattern出现次数

 //KMP算法,统计pattern在text中出现的次数
 int KMP(char text[],char pattern[]) 
 {
 	int n = strlen(text),m = strlen(pattern);
 	getNext(pattern,m);
 	int ans = 0,j = -1;
 	for(int i = 0 ; i <n ; i++)
 	{
 		while(j != -1 && text[i] != pattern[j+1])
 		{
 			j = next[j];
		 }
		 if(text[i] == pattern[j + 1])
		 {
		 	j++;
		 }
		 if(j == m - 1)
		 {
		 	ans++;
		 	j = next[j];
		 }
	 }
	return ans; 
 }

求解nextval数组

// getNextval求解长度为len的字符串s的nextval数组
void getNextval(char s[],int len)
{
	int j = -1;
	nextval[0] = -1;//初始化j=next[0] = -1 
	for(int i = 1;i < len;i++)//求解next[1] ~ next[len - 1] 
	{
		while(j != -1 && s[i] != s[j+1])
		{
			j = nextval[j];//反复令j = next[j] 
		}
		if(s[i] == s[j + 1])//如果s[i] == s[j+1] 
		{
			j++;//则next[i] = j + 1,先令j指向这个位置 
		}
		//与getNext数组相比只有此处不同 
		if(j == -1 || s[i+1] != s[j+1])
		{
			nextval[i] = j; 
		}
		else
		{
		nextval[i] = nextval[j];	
		}
		
	}
 } 

有限状态状态自动机,KMP从初始到终止的状态转移。
扩展:AC自动机(非严肃解释,仅用来帮助理解KMP算法)
通常把解决多维字符串匹配(一个文本串匹配多个字符串)的算法称为AC自动机

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值