关于串的循环移动与最小覆盖几个问题
来源:互联网 发布:知进退呼为神 编辑:程序博客网 时间:2024/06/04 12:47
以下对于串的加法即连接操作,数乘n表示复制n次,|S|表示串S长度,先yy几个名词
分子串:如果串S = k×S'(其中k>=1),则称S'为S的一个分子串。
原子串:所有S'中长度最小的称为S的原子串,记为S*。
覆盖串:如果串|S''| <= |S|,且有S为k×S''(其中k>=1)的前缀,则称S''为S的一个覆盖串。
最小覆盖串:所有S''中长度最小的称为S的最小覆盖串,记为S^。
例1:S=“abcabcabcabc”,其中一个S’=“abcabc”,S*=“abc”,其中一个S''=“abcabc”,S^=“abc”。
例2:S=“abcabcab”,只有一个S'=“abcabcab”,S*=“abcabcab”,其中一个S''=“abcabc”,S^=“abc”。
结论1. 一个串能够循环移动m位的到自身,令g=gcd(|S|,m),则S[0...g-1]为S的一个分子串,也即S可划分为k(其中k=|S|/g)个完全相同串。
证明:将串S想象成一个|S|个节点的环,其中位置固定的,例如S="abcabc"可表示为图1,对S循环右移2位得到“bcabca”图2,这实际上相当于将每个节点中的字符按图示箭头移动图3。
如果串S循环移动后得到自身,实际上说明了有边相连的节点的字符相同,如将“abc”循环右移3位图4。
为了观察到规律,我们假设一长度为9的串循环右移6位后得到自身,现仅考虑位置0,6,3的移动情况图5,首先可以
得出位置0与位置6字符相同,之后可以的出位置6与位置3字符相同,最后是位置3与位置0。想到什么了吗?
从0到6:(0+6) mod 9,从6到3:(6+6) mod 9,从3到0:(3+6) mod 9,之后一直循环。
同理可以得到位置1,7,4字符相同,位置2,8,5字符相同,即其可划分为3个长度为3的完全相同的串图6,颜色相同表示字符相同。
考虑一般情况,长度为n的串循环移动m位的到自身,则可已得到位置(0+k×m) mod n与位置0字符相同,位置(1+k×m) mod n与位置1字符相同,...,令g=gcd(n,m),由公约数定理可知
位置0,g,...,n-g上字符相同
位置1,g+1,...,n-g+1上字符相同
...
位置g-1,g-1+g,...,n-g+g-1等于n-1上字符相同。
从而S可划分为n/g个长度为g的完全相同的字符,结论得证。
结论 2. 若串S存在原子串S*≠S,则有串S的最小覆盖串S^=S*。
证明:首先易知S*可以覆盖S。
假设S*≠S^,有三种情况,|S*|<|S^|,|S*|=|S^|,|S*|>|S^|。
|S*|<|S^|时,由于S*可以覆盖S,这与S^定义相矛盾。
|S*|=|S^|时,易知与假设相矛盾。
|S*|>|S^|时,先考虑一个具体例子,设|S|=18,|S*|=6,|S^|=4。
由S与S*的关系我们可以得到(未全列出)S[0]=S[6],S[1]=S[7],S[2]=S[8],S[3]=S[9],S[4]=S[10],S[5]=S[11]。
由S与S^的关系我们得到(未全列出)S[0]=S[4],S[1]=S[5],S[2]=S[6],S[3]=S[7],S[4]=S[8],S[5]=S[9],S[6]=S[10],S[7]=S[11]。
现在我们只考虑与S[0]相同的字符(仅考虑前6×2个位置),可以得出以下推导过程:S[0]=S[4]=S[8]=S[2]=S[6]=S[0]
实际上是:(0+4) mod 6 = 4,(4+4) mod 6 = 2,(2+4) mod 6 = 0。
同理得到S[1]=S[3]=S[5],这样就把S*分成了完全相同的3的串S*' = S[0,1],易证S*'为S的原子串,这与S*为原子串相矛盾。
考虑一般情况,设|S|=L,|S*|=m<L,|S^|=n<m。
设g=gcd(m,n),有上面的分析及公约数定理我们可以得到:
S[0]=S[(0+n) mod m]=S[(0+2×n) mod m] = ... = S[g]
S[1]=S[(1+n) mod m]=...=S[g+1]
...
S[g-1]=S[(g-1+n) mod m] = ...=S[2×g-1]
这样,容易证明S[0,...,g-1]为S的原子串,且g<m,这与假设相矛盾,固有S*=S^。
以上俩个结论的证明都用到了公约数理论,非常类似,故将它们放到一起。
推论 1.由结论1与结论2我们可以得到所有的分子串S'=k×S*。
结论 3.设next[0,...,L](注意不是nextval)为S[0,...,L](注意实际上字符串为S[0,...,L-1],其中S[L]='\0')经KMP预处理得到数组,则有S[0,...,L-next[L]-1]为S的最小覆盖串。
首先由next函数定义易知S[0,...,L-next[L]-1]可以覆盖S,所以只需证其是长度最小的覆盖串。
设m=L-next[L],假设存在n<m使得S[0,...,n-1]为S的覆盖串,则容易得到S[0,...,L-n-1]=S[n,...,L-1],
由n<m可知L-n>L-m,故next[L]应为L-n,这与假设相矛盾,故原结论成立。
推论 2.由结论2和结论3可以的到如果|S| mod (|S|-next[|S|]) ≠ 0,则S不存在非平凡分子串(原子串)。
- 关于串的循环移动与最小覆盖几个问题
- 关于“foreach循环”中遇到的几个问题总结
- 关于移动PPC广告你所需要考虑的几个问题
- 关于指针的几个问题与解答
- 关于Java与C类型的几个问题
- 关于FDDB与YOLO的几个问题
- KMP与最小覆盖子串
- KMP与最小覆盖子串
- KMP与最小覆盖子串
- 关于二分图中对最小顶点覆盖、最小边覆盖、最大独立集的总结
- 图论中 [ 最小边覆盖/最小路径覆盖/最小顶点覆盖/最大独立集/最大团 ] 的概念与性质
- 最小边覆盖与最小路径覆盖的联系与区别
- 最小边覆盖与最小路径覆盖的联系与区别
- 关于数组循环移动的实现
- 关于《仙剑》的几个问题
- 关于CCheckListBox的几个问题!
- 关于网络的几个问题
- 关于分区的几个问题
- 用apktool批量反编译apk文件
- 网络异步Get请求之block方法
- jQuery Ajax实现下拉框无刷新联动
- 【移动开发】Android中WIFI开发总结(一)
- E: 未发现软件包 install_flash_player_11_linux.x86_64.tar.gz
- 关于串的循环移动与最小覆盖几个问题
- 华为机试—输出含“23”的数
- opencv: converting color 后序
- makefile的编写和使用
- 如何配置EditPlus编译运行Java程序?
- 第三章思维导图
- c++11 静态断言
- iOS性能优化
- 【移动开发】Android中WIFI开发总结(二)