KMP算法的next数组值推导

next数组值的推导

next数组值只与模式串相关(子串是主串的子集)

n e x t [ j ] = k next[j]=k next[j]=k ,则 n e x t [ j ] next[j] next[j] 表明当模式串T中第 j j j 个字符与主串S中相应字符匹配失败时,模式串T的下标应该变为 k k k 值后再与主串S中的该字符进行比较

在前后缀字符中:
零个字符相等,k值为 1
一个字符相等,k值为 2
两个字符相等,k值为 3
n 个字符相等,k值 n + 1 n+1 n+1

1.模式串T=“abcdex”(无重复字符)


因为此模式串中没有重复的字符,所以匹配失败后,均需要回到模式串首位 k = 1 k=1 k=1
j j j从 1 到 j − 1 j-1 j1
①当 j = 1 j=1 j=1 时,next[1]=0(next函数定义)???
②当 j = 2 j=2 j=2 时, j j j 从 1 到 1,从1到1的串为 a a a,next[2]=1
③当 j = 3 j=3 j=3 时, j j j 从 1 到 2,从1到2的串为 a b ab ab,next[3]=1
④当 j = 4 j=4 j=4 时, j j j 从 1 到 3,从1到3的串为 a b c abc abc,next[4]=1
⑤当 j = 5 j=5 j=5 时, j j j 从 1 到 4,从1到4的串为 a b c d abcd abcd,next[5]=1
⑥当 j = 6 j=6 j=6 时, j j j 从 1 到 5,从1到5的串为 a b c d e abcde abcde,next[6]=1

2.模式串T=“abcabx”(有重复字符)


j j j从 1 到 j − 1 j-1 j1
①当 j = 1 j=1 j=1 时,next[1]=0(next函数定义)???
②当 j = 2 j=2 j=2 时, j j j 从 1 到 1,从1到1的串为 a a a,next[2]=1
③当 j = 3 j=3 j=3 时, j j j 从 1 到 2,从1到2的串为 a b ab ab,next[3]=1
④当 j = 4 j=4 j=4 时, j j j 从 1 到 3,从1到3的串为 a b c abc abc,next[4]=1
⑤当 j = 5 j=5 j=5 时, j j j 从 1 到 4,从1到4的串为 a b c a abca abca,前缀字符为a,后缀字符为a,即有1个字符相等,即k=1+1=2,有next[5]=2

⑥当 j = 6 j=6 j=6 时, j j j 从 1 到 5,从1到4的串为 a b c a b abcab abcab,前缀字符为ab,后缀字符为ab,即有2个字符相等,k=2+1=3,next[6]=3

3.模式串T=“ababaaaba”(有重复字符)

j j j从 1 到 j − 1 j-1 j1
①当 j = 1 j=1 j=1 时,next[1]=0(next函数定义)???
②当 j = 2 j=2 j=2 时, j j j 从 1 到 1,从1到1的串为 a a a,next[2]=1
③当 j = 3 j=3 j=3 时, j j j 从 1 到 2,从1到2的串为 a b ab ab,next[3]=1
④当 j = 4 j=4 j=4 时, j j j 从 1 到 3,从1到3的串为 a b a aba aba,前缀字符为a,后缀字符为a,即有1个字符相等,k=1+1=2,next[4]=2

⑤当 j = 5 j=5 j=5 时, j j j 从 1 到 4,从1到4的串为 a b a b abab abab,前缀字符为ab,后缀字符为ab,即有2个字符相等,k=2+1=3,next[5]=3

⑥当 j = 6 j=6 j=6 时, j j j 从 1 到 5,从1到5的串为 a b a b a ababa ababa,前缀字符为aba,后缀字符为aba,即有3个字符相等,k=3+1=4,next[6]=4

⑦当 j = 7 j=7 j=7 时, j j j 从 1 到 6,从1到6的串为 a b a b a a ababaa ababaa,前缀字符为a,后缀字符为a,即有1个字符相等,k=1+1=2,next[7]=2

⑧当 j = 8 j=8 j=8 时, j j j 从 1 到 7,从1到7的串为 a b a b a a a ababaaa ababaaa,前缀字符为a,后缀字符为a,即有1个字符相等,k=1+1=2,next[8]=2

⑨当 j = 9 j=9 j=9 时, j j j从 1 到 8,从1到8的串为 a b a b a a a b ababaaab ababaaab,前缀字符为ab,后缀字符为ab,即有2个字符相等,k=2+1=3,next[9]=3

4.模式串T=“aaaaaaaab”(有重复字符)

j j j从 1 到 j − 1 j-1 j1
①当 j = 1 j=1 j=1 时,next[1]=0(next函数定义)???
②当 j = 2 j=2 j=2 时, j j j 从 1 到 1,从1到1的串为 a a a,next[2]=1
③当 j = 3 j=3 j=3 时, j j j 从 1 到 2,从1到2的串为 a a aa aa,前缀字符为a,后缀字符为a,即有1个字符相等,k=1+1=2,next[3]=2

④当 j = 4 j=4 j=4 时, j j j 从 1 到 3,从1到3的串为 a a a aaa aaa,前缀字符为aa,后缀字符为aa,即有2个字符相等,k=2+1=3,next[4]=3

⑤当 j = 5 j=5 j=5 时, j j j 从 1 到 4,从1到4的串为 a a a a aaaa aaaa,前缀字符为aaa,后缀字符为aaa,即有3个字符相等,k=3+1=4,next[5]=4

⑥当 j = 6 j=6 j=6 时, j j j 从 1 到 5,从1到5的串为 a a a a a aaaaa aaaaa,前缀字符为aaaa,后缀字符为aaaa,即有4个字符相等,k=4+1=5,next[6]=5

⑦当 j = 7 j=7 j=7 时, j j j 从 1 到 6,从1到6的串为 a a a a a a aaaaaa aaaaaa,前缀字符为a,后缀字符为a,即有5个字符相等,k=5+1=6,next[7]=6

⑧当 j = 8 j=8 j=8 时, j j j 从 1 到 7,从1到7的串为 a a a a a a a aaaaaaa aaaaaaa,前缀字符为a,后缀字符为a,即有6个字符相等,k=6+1=7,next[8]=7

⑨当 j = 9 j=9 j=9 时, j j j从 1 到 8,从1到8的串为 a a a a a a a aaaaaaa aaaaaaa,前缀字符为ab,后缀字符为ab,即有7个字符相等,k=7+1=8,next[9]=8


假设模式串的第一位与主串匹配失败
next[1] T [ 1 ] T[1] T[1] 前无字符,谈不上公共前后缀字符

next[1]=0:模式串下标由1“跳”到0


假设模式串的第二位与主串匹配失败
next[2]:下标为2的位置匹配失败后,模式串的下标应该跳到哪一个位置继续与主串当前位置进行比较

T [ 2 ] T[2] T[2] 前仅有一个字母A,无公共前后缀字符,所以 j = 0 + 1 = 1 j=0+1=1 j=0+1=1

next[2]=1:模式串第2位匹配失败后,接着用模式串下标为1的字符与主串当前位置进行比较


假设模式串的第三位与主串匹配失败
next[3]:下标为3的位置匹配失败后,模式串的下标应该跳到哪一个位置继续与主串当前位置进行比较

T [ 3 ] T[3] T[3] 前仅有字母AB,无公共前后缀字符,所以 j = 0 + 1 = 1 j=0+1=1 j=0+1=1

next[3]=1:模式串第3位匹配失败后,接着用模式串下标为1的字符与主串当前位置进行比较

假设模式串的第四位与主串匹配失败
next[4]:下标为4的位置匹配失败后,模式串的下标应该跳到哪一个位置继续与主串当前位置进行比较

T [ 4 ] T[4] T[4] 前子串为“ABA”,有 1 1 1 对公共前后缀字符,最大公共前后缀长度为1,故 j = 1 + 1 = 2 j=1+1=2 j=1+1=2

将模式串“移动”到后缀字符位置

next[4]=1+1=2:模式串第3位匹配失败后,接着用模式串下标为2的字符与主串当前位置进行比较


假设模式串的第五位与主串匹配失败
next[5]:下标为5的位置匹配失败后,模式串的下标应该跳到哪一个位置继续与主串当前位置进行比较

T [ 5 ] T[5] T[5] 前有子串“ABAB”,有 2 2 2 对公共前后缀字符,最大公共前后缀字符长度为2,故 j = 2 + 1 = 3 j=2+1=3 j=2+1=3

将模式串“移动”到后缀字符位置

next[5]=2+1=3:模式串第5位匹配失败后,接着用模式串下标为3的字符与主串当前位置进行比较


假设模式串的第六位与主串匹配失败
next[6]:下标为6的位置匹配失败后,模式串的下标应该跳到哪一个位置继续与主串当前位置进行比较

T [ 6 ] T[6] T[6] 前子串为“ABABA”,有3对公共前后缀字符,最大公共前后缀字符长度为3,故 j = 3 + 1 = 4 j=3+1=4 j=3+1=4

将模式串“移动”到后缀字符位置

next[6]=3+1=4:模式串第6位匹配失败后,接着用模式串下标为4的字符与主串当前位置进行比较

next数组代码

void get_next(String T, int next[]){	//数组next
	int i=1,j=0;
	next[1]=0;
	while(i < T.length){ 
		if(j == 0 || T.ch[i] == T.ch[j] ){	//前缀字符等于后缀字符
			++i;
			++j;
			next[i]=j;	//将模式串由前缀位置“移动”到后缀位置
		}else
			j = next[j];	//字符不同,j值回溯
	}
}

代入本篇文章的一个示例来走一遍程序

程序开始
i = 1 , j = 0 i=1,j=0 i=1j=0,next[1]=0
进入while循环
第一次循环: j = 0 j=0 j=0,自增后 i = 2 , j = 1 i=2,j=1 i=2j=1,next[2]=1
第二次循环: i = 2 , j = 1 , T [ 2 ] ≠ T [ 1 ] i=2,j=1,T[2] \ne T[1] i=2j=1T[2]=T[1],j=next[1]=0
第三次循环: j = 0 j=0 j=0,自增后 i = 3 , j = 1 i=3,j=1 i=3j=1,next[3]=1
第四次循环: i = 3 , j = 1 , T [ 3 ] ≠ T [ 1 ] i=3,j=1,T[3] \ne T[1] i=3j=1T[3]=T[1],j=next[1]=0
第五次循环: j = 0 j=0 j=0,自增后 i = 4 , j = 1 i=4,j=1 i=4j=1,next[4]=1
第六次循环: i = 4 , j = 1 , T [ 4 ] = T [ 1 ] i=4,j=1,T[4]=T[1] i=4j=1T[4]=T[1],自增后 i = 5 , j = 2 i=5,j=2 i=5j=2,next[5]=2
第七次循环: i = 5 , j = 2 i=5,j=2 i=5j=2,自增后 i = 6 , j = 3 i=6,j=3 i=6j=3,next[6]=3

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Uncertainty!!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值