循环串问题

来源:互联网 发布:剑网3a卡优化 编辑:程序博客网 时间:2024/05/16 08:17

首先了解一下最小覆盖串问题即求一个最小的子串使其能够通过复制的方法覆盖整个子串(不用恰好覆盖,可以多出来一块)

例如: ABCDABCDAB 的最小覆盖子串为:ABCD

假设字符串的存储空间为 str[0]~str[len-1], next数组是KMP算法的回溯数组,

一个字符串的最小覆盖子串为str[0]~str[n-1],当且仅当n == len-next[len],

证明见:http://blog.csdn.net/fjsd155/article/details/6866991


循环串问题:即给出一个字符串通过循环后移的操作(即串的每个字符都向后移动一个单位,其中最后一位移动到最前面),重复这样的操作n次,字符串和原串相同,n就叫做该串的循环周期,要求求出最小的循环周期,显然对于任意一个字符串,都有其平凡周期len。这个问题可以通过最小表示法和求原串在加倍串中的匹配来求解,但下面给出一个利用循环串内部性质的解法

用群论的方法可以很好的解决该问题,我们定义一个代数系统< S , *> ,其中S是对给定串的操作(即循环后移不同次),为了描述方便用->^(a1)表示对给定串循环后移a1次, s1 相当于->^(a1),s1*s2可以定义为先把串循环后移a1次,在循环后移a2次,容易证明<S, *>是由->^(1)为生成员的生成群,设该群的的生成周期为k,则因为->^(len) 等价->^(k),所以必有len能被k整除所以我们可以用串的str[0]~str[k-1]恰好覆盖整个串,而且这个是最小覆盖串(如果不是的话,假设是str[0]~str[k1],那就存在k1 < k使得  ->^(k1) 等价 ->^(k),这与假设相矛盾)。

结论 ,判断一个串是否为循环串只要求其自身的next数组判断(len-next[len]能否整除len即可),而其最小循环周期为len-next[len]

原创粉丝点击