所谓的next数组就是在我们需要查找字符串前,先对要查找的字符串做一个分析而这个分析就是要找出前面字符串的最长真前后缀相等的字符个数。
那么问题来了什么是真前后缀呢?
字符串的真前缀:符号串左部的任意子串,但不包含本身。
字符串的真后缀:符号串右部的任意子串,但不包含本身。
这样只靠文字还是有点晦涩。直接看一个例子吧:abcabe
真前缀:a,ab,abc,abca,abcab
真后缀:e,be,abe,cabe,bcabe
真前后缀搞懂了,接下来尝试写出一个字符串的next数组!
j | 123456 |
---|---|
模式串T | abcabe |
next[j] |
而根据next[j]的定义得next[0]=0,next[1]=1;
1. j=3时,前面的字符串为ab,真前缀为a,真后缀为b,不相等,相等的字符个数为0,所以接下来要从第一个开始比较,因此next[j]=1。
2. j=4时,前面的字符串为abc,真前缀为a,ab,真后缀为bc,c,没有一个相等的,相等的字符个数为0,所以接下来要从第一个开始比较,因此next[j]=1。
3. j=5时,前面的字符串为abca,真前缀为a,ab,abc,真后缀为bca,ca,a,此时有相等的,找出最长的那个,即真前缀a与真后缀a相等的字符个数为1,所以接下来要从第2个开始比较,因此next[j]=2。
4. j=6时,前面的字符串为abcab,真前缀为a,ab,abc,abca,真后缀为bcab,cab,ab,b,此时有相等的,找出最长的那个,即真前缀ab与真后缀ab相等的字符个数为2,所以接下来要从第3个开始比较,因此next[j]=3。
最终结果为
j | 123456 |
---|---|
模式串T | abcabe |
next[j] | 011123 |
想必你已经初步掌握了,接来给个例子尝试一下吧!
ababaaa
答案如下图:
j | 1234567 |
---|---|
模式串T | ababaaa |
next[j] | 0112342 |
next[0]=0,next[1]=1,这个不用多说由定义得到即下图:
j | 1234567 |
---|---|
模式串T | ababaaa |
next[j] | 01.……. |
当j=3,此时真前后缀分别为(a)和(b),最长相等的字符串中字符个数为0,所以next[3]=1。即下图:
j | 1234567 |
---|---|
模式串T | ababaaa |
next[j] | 011……. |
当j=4,此时真前后缀分别为(a,ab)和(a,ba),都有a,最长相等的字符串中字符个数为1,所以next[4]=2。即下图:
j | 1234567 |
---|---|
模式串T | ababaaa |
next[j] | 0112.…. |
当j=5,此时真前后缀分别为(a,ab,aba)和(b,ab,bab),都有ab最长相等的字符串中字符个数为2,所以next[5]=3。即下图:
j | 1234567 |
---|---|
模式串T | ababaaa |
next[j] | 01123…. |
当j=6,此时真前后缀分别为(a,ab,aba,abab)和(a,ba,aba,baba),都有a,aba最长相等的字符串中字符个数为3,所以next[6]=4。即下图:
j | 1234567 |
---|---|
模式串T | ababaaa |
next[j] | 011234. |
当j=7,此时真前后缀分别为(a,ab,aba,abab,ababa)和(a,aa,baa,abaa,babaa),都有a最长相等的字符串中字符个数为1,所以next[7]=2。即下图:
j | 1234567 |
---|---|
模式串T | ababaaa |
next[j] | 0112342 |
OK!想必你已经掌握了这个方法了!接下讨论next数组的改进nextval数组。
它是计算出next值的同时,如果a位字符与它next值指向的b位字符相等,则改a位的nextval就指向b位的nextval的值,如果不相等,则改a位的nextval值就是它自己a位的next的值。
就对上个例子进行改进一下。
j | 1234567 |
---|---|
模式串T | ababaaa |
next[j] | 0112342 |
nextval | 0101042 |
1.当j=1时,nextval[1]=0。
2.当j=2时,因第二位字符b的next值为1,而第一位就是a,他们不相等,所以nextval[2]=next[2]=1。
3.当j=3时,因第三位字符a的next值为1,而第一位也是a,他们相等,所以nextval[3]=nextval[[1]=0。
4.当j=4时,因第四位字符b的next值为2,而第二位也是b,他们相等,所以nextval[4]=nextval[[2]=1。
5.当j=5时,因第五位字符a的next值为3,而第三位也是a,他们相等,所以nextval[5]=nextval[[3]=0。
6.当j=6时,因第六位字符a的next值为4,而第四位也是b,他们不相等,所以nextval[5]=next[[5]=4。
7.当j=7时,因第七位字符a的next值为2,而第二位也是b,他们不相等,所以nextval[7]=next[[7]=2。
以上就是我对KMP算法中next及nextval数组的解法。
欢迎大家在评论区交流。