next数组(详细求法)

简介: next数组(详细求法)

Next数组

话不多说,咱们直接通过问题来分析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;
} 


目录
相关文章
筛质数、分解质因数和快速幂的应用
筛质数、分解质因数和快速幂的应用
70 0
|
C语言
next数组的两种求法详解及完整代码
求字符串的next数组: 方法一: 这里我们将next数组第1,2位分别设为0,1(还有-1,0这种设法,这里先将其设为0,1若有需要再减一即可) 后面求解每一位的next值时,根据前一位进行比较。 从第三位开始,将前一位与其next值对应的内容进行比较, 如果相等,则该位的next值就是前一位的next值加上1; 如果不等,向前继续寻找next值对应的内容来与前一位进行比较, 直到找到某个位上内容的next值对应的内容与前一位相等为止, 则这个位对应的值加上1即为需求的next值; 如果找到第一位都没有
414 0
next数组的两种求法详解及完整代码
一个求公约数和公倍数的有趣求法
一个求公约数和公倍数的有趣求法
66 0
|
算法
看了这个你基本就会算kmp算法的next数组了
看了这个你基本就会算kmp算法的next数组了
杨氏矩阵,字符串左旋,字符串旋转结果题目解析
杨氏矩阵,字符串左旋,字符串旋转结果题目解析
子数组问题总结(很多子数组求法类似,暴力求法)
子数组问题总结(很多子数组求法类似,暴力求法)
子数组问题总结(很多子数组求法类似,暴力求法)
|
算法 Java
判断回文串(hdu 2029)双指针法
题目来自 hdu 杭州电子科技大学的一个算法网站
|
算法
7-142 最大子列和问题
7-142 最大子列和问题
73 0

热门文章

最新文章