数据结构——求KMP算法的next[j]
一、next[j] 函数定义如下
二、模式串为:abababb,设模式串第一个字符的下标为0
三、求next[j]的第一种方法——前缀后缀最大公共元素长度法
1、j = 0,p = a,前缀后缀最大公共元素长度 = 0
● 无前后缀
2、j = 1,p = ab,前缀后缀最大公共元素长度 = 0
● 前缀:a
● 后缀:b
● a != b
3、j = 2,p = aba,前缀后缀最大公共元素长度 = 1
● 前缀:a,ab
● 后缀:a,ba
● a == a,ab != ba
4、j = 3,p = abab,前缀后缀最大公共元素长度 = 2
● 前缀:a,ab,aba
● 后缀:b,ab,bab
● a != b, ab == ab,aba != bab
5、j = 4,p = ababa,前缀后缀最大公共元素长度 = 3
● 前缀:a,ab,aba,abab
● 后缀:a,ba,aba,baba
● a == a, ab != ba,aba == aba,abab != baba
6、j = 5,p = ababab,前缀后缀最大公共元素长度 = 4
● 前缀:a,ab,aba,abab,ababa
● 后缀:b,ab,bab,abab,babab
● a != b, ab == ab,aba != bab,abab == abab,ababa != babab
7、j = 6,p = abababb,前缀后缀最大公共元素长度 = 0
● 前缀:a,ab,aba,abab,ababa,ababab
● 后缀:b,bb,abb,babb,ababb,bababb
● a != b, ab != bb,aba != abb,abab != babb,ababa != ababb,ababab != bababb
8、综上所述,模式串abababb 各个子串的前缀后缀最大公共元素长度为:
因此,将「最大公共元素长度」行的元素整体向右移动,第一个位置填上-1,即求得next[j]
※ 当然,向右平移后的操作是根据j的初始值决定的
※ 这里,j的初始值是0
※ 如果j的初始值 > 0,则模式串向右平移后,对应的next[j]中的每个值都要加上j的初始值,才是最终的next[j]
※ 第四版的《软件设计师教程》的这部分计算有误
四、求next[j]的第二种方法——公式代入法
1、由于模式串的第一个字符的下标为0,即j 的值从0开始,依次为 0、1、2、3、4、5、6
2、当 j = 0时,根据 next[j] 函数 的定义可知,此时 next[0] = -1
3、当 j = 1 时,不满足①号情况,看②号
● max{k | 0 < k < j且"p0 …… pk-1" = " pj-k …… pj-1"}
● 该函数的意思是:取k满足 0 < k < j && "p0 …… pk-1" = " pj-k …… pj-1" 条件时的最大的值
● 由于 j = 1,则 k 必须满足 0 < k < 1 才行,但是k必须是正整数,因此不满足条件,即不满足 ② 号情况
● 因此,当 j = 1时,属于③ 号情况,即:next[1] = 0
4、当 j = 2 时,不满足① 号情况,看②号
● 由于 j = 2,此时 0 < k < 2,k 可能满足条件的取值只有1,看后面的条件
● p0 代表 模式串中的第一个字符a,p0p1 代表ab,p0p1p2p3p4p5p6 代表 abababb,即模式串本身
● 因此,根据j 和k 的取值,可得到以下情况
● j = 2, k = 1,则:p0 = p1 ,由模式串可知,该条件不满足,②号 不满足,属于③ 号情况,即:next[2] = 0
5、当 j = 3时,不满足① 号情况,看②号
● 当j = 3时,0 < k < 3,k 可能满足条件的取值有{1,2}
● 依次遍历 k 的取值,并组合 j 的值
● j = 3,k = 1时,p0 = p2根据模式串可知为true
● j = 3,k = 2时,p0p1 = p1p2 根据模式串可知为false
● 因此 next[3] = 1
6、当 j = 4时,不满足① 号情况,看②号
● 当j = 4时,0 < k < 4,k 可能满足条件的取值有{1,2,3}
● 依次遍历 k 的取值,并组合 j 的值
● j = 4,k = 1时,p0 = p3根据模式串可知为false
● j = 4,k = 2时,p0p1 = p2p3根据模式串可知为true
● j = 4,k = 3时,p0p1p2 = p1p2p3根据模式串可知为false
● 因此,情况② 存在一个k的值满足条件,即 k = 2,因此 next[4] = 2
7、 当 j = 5时,不满足① 号情况,看②号
● 当j = 5时,0 < k < 5,k 可能满足条件的取值有{1,2,3,4}
● 依次遍历 k 的取值,并组合 j 的值
● j = 5,k = 1时,p0 = p4根据模式串可知为true
● j = 5,k = 2时,p0p1 = p3p4根据模式串可知为false
● j = 5,k = 3 时,p0p1p2 = p2p3p4根据模式串可知为true
● j = 5,k = 4 时,p0p1p2p3 = p1p2p3p4根据模式串可知为false
● 当k = 1 和 k = 3 时,公式都满足,取max{1,3}后, next[5] = 3
8、当 j = 6时,不满足① 号情况,看②号
● 当j = 6时,0 < k < 6,k 可能满足条件的取值有{1,2,3,4,5}
● 依次遍历 k 的取值,并组合 j 的值
● j = 6,k = 1时,p0 = p5根据模式串可知为false
● j = 6,k = 2时,p0p1 = p4p5根据模式串可知为true
● j = 6,k = 3时,p0p1p2 = p3p4p5根据模式串可知为false
● j = 6,k = 4时,p0p1p2p3 =p2 p3p4p5根据模式串可知为true
● j = 6,k = 4时,p0p1p2p3p4 = p1p2p3p4p5根据模式串可知为false
● 当k = 2 和 k = 4 时,公式都满足,取max{2,4}后, next[6] = 4
9、因此, next[j] = [-1,0,0,1,2,3,4]