关于串的循环移动与最小覆盖几个问题

来源:互联网 发布:知进退呼为神 编辑:程序博客网 时间: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不存在非平凡分子串(原子串)。



 


0 0
原创粉丝点击