个人理解---KMP与Next数组详解

Kmp就是求子串在母串中的位置等相关问题;当然KMP最重要的是Next数组,也称失败数组,Next[i]代表的意思是子串 sub 从sub[0] 到 sub[i-1]的前缀和后缀的最大匹配。模拟KMP实现过程:用两个指针 i 和 j 分别指向母串和子串,当Mum[i]=sub[j]时 i++,j++;如果不相等:我们就要让 j 减小,我们既要让j最大,又要让母串中的前j个字符和子串的后j个字符相同,所以 j 就变成了Next[j];
 
 
以上配图来源于ccx学长:
 
int KMP(char Mum[], char Sub[])//求子串Sub在母串Mum第一次出现的开始下标,下标从0开始; 
{
	int Lm = strlen(Mum);
	
	int Ls = strlen(Sub);
	
	int i = 0, j = 0;
	
	while(i < Lm)
	{
		if(j==-1 || Mum[i]==Sub[j])//当第一个字母都不同时,j会减小为Next[j]=-1,但是不能再减了
		{
			i++;
			j++; 
		}
		else
			j = Next[j];
		
		if(j==Ls)//当j到达了子串的长度说明已经匹配完成;
			return i-Ls; 
	}
}

  

 
对于Next[]怎么求:就是单独处理子串,同样用两个指针i和j指向子串的前面部分和后面部分,如果sub[i]=sub[j],Next[j+1] = Next[j]+1; 所以就有了i++,j++;Next[j] = i;就说明前面的0-i字符和后面的(j-1-i)-(j-1)的字符一样的;如果不相等,就让i为Next[i]相当于求自己的前面部分在串中出现的位置,而且要让前面部分的长度越长越好;
 
void GetNext(char Sub[])
{
	int Ls = strlen(Sub);
	
	int i, j;
	
	Next[0] = -1;
	
	i = -1; j = 0;
	
	while(j < Ls)
	{
		if( i==-1 || Sub[i] == Sub[j])//当满足这个条件时; 都要向后退一个;并且要更新Next; 
		{
			i ++;
			j ++;
			Next[j] = i;//Next[j] = Next[j-1] + 1;写成这种形式,我感觉也行,但是有些题目过不了-_-; 
		}
		else
		
			i = Next[i];
	}
}

  

原文地址:https://www.cnblogs.com/zhengguiping--9876/p/5292330.html