串,KMP算法,next[]值

有一篇关于模式串回溯多少位的解释 -----------》解释
串,KMP算法,next[]值_第1张图片
1:比较不经常考,主要描述比较出名的KMP算法及其next值的来由
2:求next[]值,有两个版本,分为开头next[1]自定义为0和next[1]自定义为-1,其实思想都一样

串,KMP算法,next[]值_第2张图片

我的求next数组的思想是

对于第j个字符来讲,其毗邻(不可间断)的前方(前方:第一个字符不算)是否存在着一个长度为n的子串,与以头开始的n个字符匹配,若匹配(亦可以说:无论匹不匹配 [不匹配的话n就为0]),则next[j]=n+1;我觉得’+1’这个操作,正是为什么数组名叫‘next’的精髓

算法的口头描述:开头next[1]自定义为0
j=2:对于j=2的b来讲,前方存在0个长度(不算第一个a,下同)的子串(子串的最后一个必须是下标为j-1的那个字母(毗邻的意思),下同)与开头的a匹配,故next[2]=0+1=1
j=3:对于j=3的a来讲,前方存在一个长度为0的子串与开头的a匹配,故next[3]=0+1=1
j=4:对于j=4的a来讲,前面存在一个长度为1的a(j=3)子串与开头a匹配故而,next[4]=1+1=2
j=5:对于j=5的b来讲,前面存在一个长度为1的a(j=4)与开头的a匹配故而,next[5]=1+1=2
j=6:对于j=6的c来讲,前面存在一个长度为2的a(j=4)b(j=5)与开头的a和b匹配故而,next[6]=2+1=3
j=7:对于j=7的a来讲,前面存在一个长度为0的子串与开头的a匹配故而,next[7]=0+1=1
j=8:对于j=8的c来讲,前面存在一个长度为1的a(j=7)子串与开头的a匹配故而,next[0]=1+1=2

int next[8];
void get_next(char T[],int next[]){
	int i=1,j=0;next[1]=0;
	while(i<8){
		if(j==0 || T[i]==T[j]){
			++i,++j,next[i]=j;
		}
		else j=next[j];		
	}
}
int KMP(char S[],char T[],int pos){
	int i=pos,j=1;
	while(i<=12&&j<=8){
		if(j==0 || S[i]==T[j]){
			++i,++j;
		}
		else j=next[j];
	}
	if(j>8) return i-8;
	else return 0;
}
void testkmp(){
	char S[13]={' ','a','a','a','b','a','a','b','c','a','c','b','b'};
	char T[9]={' ','a','b','a','a','b','c','a','c'};
	int i=0,j=0;
printf("next值:\n");	get_next(T,next);
		for(i=1;i<=8;i++) printf("%d",next[i]);
	i=KMP(S,T,1);
	printf("\n pos=%d",i);
}

串,KMP算法,next[]值_第3张图片

你可能感兴趣的:(数据结构,字符串,数据结构,c语言,c算法)