KMP算法next推导

KMP算法next推导

  (2010-07-20 19:11:30)
标签: 

杂谈

分类: MSN搬家

上回说到.要确保P0,P1,…………Pk-1 = Pj-k, …………Pj-1这个表达式成立

则需要找到里面的k值,next有以下定义:

未命名

既然是推导,肯定要设定一些条件.我们假设

已有next[j] = k ,求next[j+1] = ?

既然已有next[j] = k,那么肯定有.P0,P1,…………Pk-1  =  Pj-k, …………Pj-1,但我们对于Pk 和 Pj的关系不清楚,让我们分开讨论

如果此时Pk = Pj

那么肯定有 P0,P1,…………Pk-1  =  Pj-k, …………Pj-1,Pj 明显看到左右的长度都加了1.也就是说在原来的基础上长度加了1.

则 next[j+1] = next[j] + 1 = k + 1;

如果此时Pk ≠ Pj

这地方很绕...最起码我学习的时候是...请详细看,我也尽量分析的详细点.

说明不会含有[0,k]长度的字符串与[k+1,j-1]

虽然这个不相等,但有可能比k小的前缀是相等的.但到底Pj 和前面的哪个字符串相等呢?

这是不是又牵扯到一个模式匹配的问题捏?  答案是的.

把模式串的后面部分看作新的主串 Pj-k, …………Pj-1,Pj

模式串前面部分看作新的模式串  P0,P1,…………Pk-1,Pk 去寻找新的匹配k'

这时候的步骤是:

1:出现了Pj和Pk不同.这时候根据KMP算法,需要回溯P产生k'.其实就是移动next(k).

2:由于带入后末尾2个匹配就是一样的了.Pk' = Pj 所以就可以得出,从j+1的字符之前存在一个长度为k'的最长字串

   P0……..Pk' = Pj-k’……Pj.也就是说next[j+1] = k’+1

   next[j+1] = next(k) + 1;

 

举个例子吧.

         1         2         3         4         5         6         7         8         9          10

-1

0

0

1

2

0

1

2

3

4

?

a

b

a

b

c

a

b

a

b

a

b

现在求next(10)?

分解成next(9+1) ,已知next(9) = 4 ,判断P4 == P9?

因为P4=c P9=a 所以不相等next(9+1) = next(4) + 1 = 3  请自己验证.

下面用白话解释上面的公式下,看next(9) = 4,那从9往前看4个 是abab....肯定第一个到第四个也是abab

假设如果next(10) = 5 如果从10往前面看ababa 第一个到第五个肯定也是ababa 这个是肯定的.但实际上第一个到第五个是ababc

但p[19] = a ...发现了吧是拿a和c比的.结果发现不同..

说明[0,k]长度的字符串与[k+1,j-1]是不会相同的.只有从[0,k]中找一个k'来进行小范围的匹配的...这个东西明显就是next[k]...

希望我说明白了.哈哈

 

再来一个吧next(6)?

分解成next(5+1) ,已知next(5) = 0 ,判断P5 == P0?

因为P5=a P0=a 所以相等next(5+1) = next(5) + 1 = 1  请自己验证.

 

其实next算法还有能可以优化的...因为有一种极端的情况.下回说~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值