算法-KMP-跳跃的证明

本文探讨了KMP算法中为何原串的originIndex可以跳跃,并通过反证法证明了跳跃的正确性。在匹配失败后,利用next数组确定跳跃的起源位置,确保下次匹配的正确性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

KMP算法,非常经典。现在只考虑一个问题,为什么原串的 originIndex 能跳跃?

现在准备两个串 origin 和 match ,长度分别是 N 和 M ,分别代表原串和匹配串。

有 next 数组,下标为 nextIndex 的值代表:match 串 nextIndex 之前(不包含)前缀后缀能匹配的最长长度。


假设现在 origin 的下标是 k , match 的下标是 0 ;进行匹配的结果是 match 匹配到 f 的时候,匹配失败。

设 n = next[f] ,那么根据 KMP 算法,跳跃的 originIndex 将会是 k+1,k+2 ~~ k+f-n-1

即下一次匹配 originIndex 将是 k+f-n 。下面是跳跃的证明,设 y=1,2 ~~ f-n-1

采用反证法进行证明。

假设存在这种情况:将 originIndex 移动到k+y的时候,匹配成功。

整理已知:

origin[k+index] == match[0+index]      index=0,1 ~~ f-1

origin[k+y+index] == match[0+index]    index=0,1 ~~ M-1

得到下面等式:

match[0] == origin[k+y+0] == origin[k+(y+0)] == match[y+0]

match[1] == origin[k+y+1] == origin[k+(y+1)] == match[y+1]

match[index] == origin[k+y+index] == origin[k+(y+index)] == match[y+index]

match[f-1-(y+1)] ==orgin[k+y+f-y-2] == origin[k+f-2] ==match[f-2]

match[f-1-(y)] == orgin[k+y+f-y-1] == origin[k+f-1] == match[f-1]

知道,match 现在有一个前缀 0 ~~ f-1-y,有一个后缀 y ~~ f-1 是完全匹配的。

而这个前缀后缀的长度是 f-y 且 n+1 <= f-y <= f-1,

即 nextIndex = f 时候,next[nextIndex] 的值是 f-y 大于原来的值 n ,在这里产生矛盾。

而当 y = f-n 时候,前后缀长度是 n,应该进行匹配判断。故 originIndex 移到 k+f-next[f]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值