证明:如果一个字符串的最小循环节是不完全循环节,那么该字符串没有完全循环节

一、相关定义及原理

以下描述中,s表示字符串,n为字符串s的长度:
s[i] s i s_i si表示字符串的第i个字符,从0开始。
使用python切片写法表示字符串的子串
s[x:y]表示字符串s下标范围为左闭右开区间[x, y)中的字符
s[:y]等价于s[0:y]
s[x:]等价于s[x:n]

  1. 循环节:若某个字符串是由某个子串循环多次构成的,那么就称该子串为原串的循环节。(本文中循环节循环次数满足大于1次)
    假设字符串s有长度为T的循环节,那么一定有: s i = s i + k T s_i=s_{i+kT} si=si+kT,k是整数。
  2. 完全循环节:字符串由若干完整的循环节构成,这样的循环节叫完全循环节。
    如果完全循环节的长度为T,那么有n%T == 0
  3. 不完全循环节:字符串由若干完整的循环节和循环节的真前缀构成。
    如果不完全循环节的长度为T,那么有n%T != 0
  4. 有长为n的字符串s,s的最短循环节为n-next[n](s的前缀表为nextnext[i]表示s的长为i的前缀s[:i]的最长相等前后缀的长度。可以使用KMP算法求出。)

二、证明

证明引理

引理1:字符串的循环节的长度都是最短循环节长度的倍数
最短循环节长度记为T
反证法:
假设存在循环节长度为U,满足 U > T U>T U>T,且U不是T的倍数。
由于最短循环节长度为T,则 s i = s i + a T s_i=s_{i+aT} si=si+aT,其中a为整数。
由于存在循环节长度为U,则 s i = s i + b U s_i=s_{i+bU} si=si+bU,其中b为整数。
因此存在 s i = s i + a T + b U s_i = s_{i+aT+bU} si=si+aT+bU,其中a、b为整数。
因为U不是T的倍数,因此可以写为 U = k T + r U = kT+r U=kT+r r r r U U U mod T T T r > 0 r>0 r>0
U > k T U>kT U>kT U < ( k + 1 ) T U<(k+1)T U<(k+1)T,亦即 U + T > ( k + 1 ) T U+T>(k+1)T U+T>(k+1)T
因此有 0 < ( k + 1 ) T − U < T 0 < (k+1)T-U < T 0<(k+1)TU<T
使a=k+1,b=-1,那么 s i = s i + ( k + 1 ) T − U s_i=s_{i+(k+1)T-U} si=si+(k+1)TU,所以存在长为(k+1)T-U的循环节。
已知T是最短循环节,而现在存在更短的长位(k+1)T-U的循环节,存在矛盾,假设不成立,原命题得证。
证明:如果一个字符串的最小循环节是不完全循环节,那么该字符串没有完全循环节
记字符串最小循环节长度为T,那么有n%T != 0
根据引理1,字符串的其他循环节长度都是最小循环节长度的倍数,为kT。k是正整数。n%(k*T) 也一定不为0。
因此该字符串没有完全循环节。

  • 20
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值