以前在网上查找next数组的处理的时候就经常能找到两种解法,对应的还是两种答案,这里就做一个个人总结
一种是正常的书上教的,可能也是大多数人学习到的next数组求解方法:
1.第一位的next值设置为0,第二位的next值设置为1 2.后面求解每一位的next值时,根据前一位进行比较。首先将前一位与其next值对应的内容进行比较,如果相等,则该位的next值就是前一位的next值加上1; 3.如果不等,向前继续寻找next值对应的内容来与前一位进行比较,直到找到某个位上内容的next值对应的内容与前一位相等为止,则这个位对应的值加上1即为需求的next值;如果找到第一位都没有找到与前一位相等的内容,那么需求的位上的next值即为1。 |
就以数组"ababaaababa"来举例:
模式串 | a | b | a | b | a | a | a | b | a | b | a |
下标 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
next数组 |
1.首先,将第1位设置为0,第2位设置为1。
模式串 | a | b | a | b | a | a | a | b | a | b | a |
下标 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
next数组 | 0 | 1 |
2.计算第3位时,看第2位的"b"的next值为1,则把"b"和下标为1对应的"a"进行比较,不同,则第3位"a"的next值为1,因为一直比到最前一位,都没有发生比较相同的现象。
式串 | a | b | a | b | a | a | a | b | a | b | a |
下标 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
next数组 | 0 | 1 | 1 |
3.计算第4位的时候,看第3位的"a"所对应的next数组为1,那么将"a"与下标为1的"a“进行比较,发现相同,那么第4位next的值就是前一位对应的1加上1,即为2
式串 | a | b | a | b | a | a | a | b | a | b | a |
下标 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
next数组 | 0 | 1 | 1 | 2 |
4.以此类推第5位,看前面第4位是"b",其next数组为2,那么就比较"b"和下标为2的"b",相同,就在2上加1,即为3。
式串 | a | b | a | b | a | a | a | b | a | b | a |
下标 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
next数组 | 0 | 1 | 1 | 2 | 3 |
5.第6位,看前面第5位是”a",对应的next数组为3,那么就比较"a"和下标为3的"a",相同,就在3的基础上加1,即为4
式串 | a | b | a | b | a | a | a | b | a | b | a |
下标 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
next数组 | 0 | 1 | 1 | 2 | 3 | 4 |
6.第7位,看前面第6位是"a",对应的next数组位4,这时候发现"a"和下标为4的"b"不同,那么,看下标为4所对应的那个"b"的next数组为2,比较"a"和下标为2的"b",又不同,就再看下标为2所对应的那个"b"的next数组为1,这时候比较“a"和下标为1的”a",发现相同,因为"a"是和下标为2的那个"b"所对应的next数组的值所对应的"a"相同,所以就在1的基础上加1,即值为2
式串 | a | b | a | b | a | a | a | b | a | b | a |
下标 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
next数组 | 0 | 1 | 1 | 2 | 3 | 4 | 2 |
7.第8位,看前面第7位是"a",对应的next数组是2,发现"a"和下标为2所对应的"b"不同,这时候看"b"的next数组为1,发现"a"和下标为1对应的"a”相同,就在1的基础上加1,即为2
式串 | a | b | a | b | a | a | a | b | a | b | a |
下标 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
next数组 | 0 | 1 | 1 | 2 | 3 | 4 | 2 | 2 |
8.第9位,看前面第8位是"b",对应的next数组是2,发现"b"和下标为2对应的"b"相同,就在2的基础上加1,为3
式串 | a | b | a | b | a | a | a | b | a | b | a |
下标 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
next数组 | 0 | 1 | 1 | 2 | 3 | 4 | 2 | 2 | 3 |
9.第10位,看前面第9位是"a",对应的next数组是3,"a"和下标为3对应的”a"相同,所以在3的基础上加1,为4
式串 | a | b | a | b | a | a | a | b | a | b | a |
下标 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
next数组 | 0 | 1 | 1 | 2 | 3 | 4 | 2 | 2 | 3 | 4 |
10.第11位,看前面第10位是"b",对应的next数组是4,发现"b"和下标为4对应的"b"相同,就在4的基础上加1,为5
式串 | a | b | a | b | a | a | a | b | a | b | a |
下标 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
next数组 | 0 | 1 | 1 | 2 | 3 | 4 | 2 | 2 | 3 | 4 | 5 |
以上就是第一种解法,这种解法完全是按照代码的方式来解next数组,在题目要求手算next数组的时候容易错
所以个人推荐在手算的时候用第二种算法,即求最大前后相同子串
还是拿ababaaababa来模拟
1.首先第一步,第一位填0
式串 | a | b | a | b | a | a | a | b | a | b | a |
下标 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
next数组 | 0 |
2.第2位,最大相同字串是0,所以也是0
式串 | a | b | a | b | a | a | a | b | a | b | a |
下标 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
next数组 | 0 | 0 |
3.第3位,最大相同字串是"a",长度为1
式串 | a | b | a | b | a | a | a | b | a | b | a |
下标 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
next数组 | 0 | 0 | 1 |
4.第4位,最大相同字串是"ab",长度为2
式串 | a | b | a | b | a | a | a | b | a | b | a |
下标 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
next数组 | 0 | 0 | 1 | 2 |
5.第5位,最大相同字串为"aba",长度为3
式串 | a | b | a | b | a | a | a | b | a | b | a |
下标 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
next数组 | 0 | 0 | 1 | 2 | 3 |
6.第6位,最大相同字串位"a",长度为1
式串 | a | b | a | b | a | a | a | b | a | b | a |
下标 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
next数组 | 0 | 0 | 1 | 2 | 3 | 1 |
7.第7位,最大相同字串为"a",长度为1
式串 | a | b | a | b | a | a | a | b | a | b | a |
下标 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
next数组 | 0 | 0 | 1 | 2 | 3 | 1 | 1 |
8.第8位,最大相同字串为"ab",长度为2
式串 | a | b | a | b | a | a | a | b | a | b | a |
下标 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
next数组 | 0 | 0 | 1 | 2 | 3 | 1 | 1 | 2 |
9.第9位,最大相同字串为"aba",长度为3
式串 | a | b | a | b | a | a | a | b | a | b | a |
下标 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
next数组 | 0 | 0 | 1 | 2 | 3 | 1 | 1 | 2 | 3 |
10.第10位,最大相同字串为"abab",长度为4
式串 | a | b | a | b | a | a | a | b | a | b | a |
下标 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
next数组 | 0 | 0 | 1 | 2 | 3 | 1 | 1 | 2 | 3 | 4 |
11.还剩下一个位置可以不用求,然后整体next数组向右移动一位,第一位空出来补-1
,这已经就是一种next数组的解法了,以-1开头
式串 | a | b | a | b | a | a | a | b | a | b | a |
下标 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
next数组 | -1 | 0 | 0 | 1 | 2 | 3 | 1 | 1 | 2 | 3 | 4 |
12.如果要转换成第一步那种,就每一项加1
式串 | a | b | a | b | a | a | a | b | a | b | a |
下标 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
next数组 | 0 | 1 | 1 | 2 | 3 | 4 | 2 | 2 | 3 | 4 | 5 |
这种方法是利用最大相同字串来解,个人认为比较适合用考试的时候遇到让你写出next数组的这种题时,手算时使用