重复字符串的判定问题(kmp 算法)

38 篇文章 0 订阅

重复字符串的判定问题,上一篇文章给出了第一种解法: 重复字符串的判定问题(质数检验法) 

该篇文章给出另一种解法,基于 kmp 算法的判定。

该算法是举例发现的,

设循环单元长度为 l, 设 len = l*n

则 [0,l) = [l, 2*l) = [2*i ,3*l ) = [3*l, 4*l) = [4*l, 5*l) = ...... = [(n-1)*l, n*l)

那么,原串必然存在前后缀相等。因而可以联想到 kmp 算法的 next 数组(在作者认知,称为t1Length 数组),

给出一个观察后的结论,如果前后缀匹配的长度是不匹配长度的整数倍(含 1)则串是重复的

构思这个解决方法时,掉过一个坑,认为只要匹配的长度大于不匹配的长度即可。举反例可以推翻这个设想:

abcabca,前后缀匹配的长度为 4,而不匹配的长度为 3,4 > 3 但是它明显不是一个重复结构。

下面证明命题:如果前后缀匹配的长度是不匹配长度的整数倍(含 1)则串是重复的


设对长为 strLen 的串计算 kmp 算法的 t1 数组的最后一个元素值 m 表示整个串前后缀匹配长度为 m,
观察整个串,若匹配的长度 m 比不匹配的长度 notC 更长,则说明它必然是一个重复的
且 m 一定是 notC 的整数倍.
这是充分必要的. 
1.假设长度为 len 的串是重复的,最小单元是 notC,则 m(len-notC)
即是 t1 数组的最后一个元素值。且 m 一定是 notC 的整数倍。
2.假设 m 是串 str 的 t1 数组最后元素的值,且 m 是 notC 的整数倍,便于理解设
m=3*notC,len=4*notC,则首先有 str[0,3*notC) = str[notC,4*notC),将 
str[0,3*notC) 分为三部分,依次与 str[notC,4*notC) 比较,可知
str[0,notC)=str[notC,2*notC), 
str[notC,2*notC)=str[2*notC,3*notC), 
str[2*notC,3*notC)=str[3*notC,4*notC)
于是有 str[0,notC)=str[notC,2*notC)=str[2*notC,3*notC)=str[3*notC,4*notC)
这也就证明了 str 是一个重复的字符串

当 m=n*notC 时,同样也可以把 str[0,n*notC) 拆为 n 部分:
str[0,notC), str[notC,2*notC).... , str[(n-1)*notC, n*notC) 依次与
str[notc,(n+1)*notC) 的 n 部分:
str[notC,2*notC).... , str[(n-1)*notC, n*notC)各项比较则可以得出
str[0,notC) = str[notC,2*notC) = ...... = str[(n-1)*notC, n*notC) = str[notc,(n+1)*notC)
因此 str 是一个重复的字符串


原理已经非常简单,t1 数组计算的方法也十分明显。问题已经非常轻松地解决了。


代码见:https://github.com/juniorfans/repeatString

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值