【数据结构】next 数组(详细求法)

发布于:2022-11-29 ⋅ 阅读:(210) ⋅ 点赞:(0)

话不多说,咱们直接通过问题来分析next数组该怎么求

Question:

设模式串"abcaababc",求它的next函数值

① 首先,我们要从左向右看,第一个字符的next[ j ]永远是0,第二个字符的next[ j ]永远是1,所以在这里,第一个字符 a 的next[ j ]是0,第二个字符 b 的next[ j ]是1,然后继续往后看,第三个字符是 c,c前面一个字符 b 的next[ j ]是1,通过1我们找到了 a,a不等于b,所以 c 的next[ j ]值是1,如下图:

j 1 2 3 4 5 6 7 8 9
模式串 t a b c a a b a b c
next [ j ] 0 1 1

② 我们继续向右,第四个字符是a,我们看第四个字符a前面的那个字符,在这里是c,然后我们看c的next[ j ]值,c的next[ j ]值为1,通过c的next[ j ]值1,我们找到了 j 为1时的模式串 t,为 a,我们发现它和c不相等,并且此时已经无法再向前寻找了,所以此时我们令第四个字符的next[ j ]为 1,如下图:

j 1 2 3 4 5 6 7 8 9
模式串 t a b c a a b a b c
next [ j ] 0 1 1 1

③ 我们继续向右,第五个字符是a,第五个字符前面一个字符(即第四个字符a)的next[ j ]为1,通过 j = 1,我们找到模式串 t 为 a,发现它和第四个字符(a)相等,那么我们就在第四个字符的next[ j ]值基础上加上1,就是第五个字符的next[ j ]值,如下图:

j 1 2 3 4 5 6 7 8 9
模式串 t a b c a a b a b c
next [ j ] 0 1 1 1 2

④ 我们继续向右,第六个字符是b,我们看它前面的那个字符 a 的next[ j ]值,顺着 a 的next[ j ]值我们找到了 b,此时 b 和 a 不相等,我们再向前寻找,再向前寻找的时候我们是通过 b的next[ j ]值进行寻找,所以我们找到了 a,注意找到的 a 还是和我们的第五个字符作比较(向前寻找始终是和要求字符的前一个字符作比较),相同,所以在第二个字符的next[ j ]基础上加上1即可,如下图: 

j 1 2 3 4 5 6 7 8 9
模式串 t a b c a a b a b c
next [ j ] 0 1 1 1 2 2 3

⑤ 我们继续向右,第七、八、九个字符同理即可,如下图:

j 1 2 3 4 5 6 7 8 9
模式串 t a b c a a b a b c
next [ j ] 0 1 1 1 2 2 3 2 3

next数组具体算法实现:

注意:这个算法算出来的每个next数组值都要比上面的理论值小1。

#include<stdio.h>
#include<malloc.h>
#include<string.h>
#define SIZE 128
#define INC 10
typedef struct String{
	char *data;
	int len;
	int size;
}String,*PString;
int Init_String(PString S){
	S->data=(char *)malloc(sizeof(char)*SIZE);
	S->len=0;
	S->size=SIZE;
	return 1;
}
int Creat_String(PString S,char *s){
	int i=0,n;
	n=strlen(s);
	while(*s!='\0'){
		if(S->size<n){
			S->data=(char *)realloc(S->data,(S->size+INC)*sizeof(char));
			S->size+=INC;
		}
		S->data[i++]=*s++;
		S->len++;
	}
	return 1;
}
void getNext(PString t,int next[]){      //next数组
	int i=0,j=-1;
	next[0]=-1;
	while(i<t->len){
		if(j==-1||(t->data[i]==t->data[j])){
			i++;
			j++;
			next[i]=j;
		}else{
		    j=next[j];	
		}
	}
	for(i=0;i<t->len;i++){
		printf("%d ",next[i]);
	}
}
int main(){
    String S;
    Init_String(&S);
    char s[100];
    int next[100];
    gets(s);
    Creat_String(&S,s);
    getNext(&S,next);
    return 0;
} 
本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到