将字符串表示为子字符串的某种幂

Posted

技术标签:

【中文标题】将字符串表示为子字符串的某种幂【英文标题】:Representation of string as some power of substring 【发布时间】:2016-06-27 14:41:06 【问题描述】:

给定一个字符串,我们必须检查一个字符串是否可以由它的子字符串重复一些有限次来表示。

ababab -> (ab)^3

我看到了一个解决方案,它说首先找到最长的正确前缀,它也是一个后缀。设这个前缀的长度是 k。设 n 为原始字符串的长度。如果 n%(n-k) == 0,则字符串可以表示为重复有限次的子字符串。否则,不。

我无法理解此解决方案背后的逻辑。谁能解释我为什么这个解决方案有效? 我看到这个解决方案的链接:geeksforgeeks

【问题讨论】:

那里给出了解释,在你给出的链接中,也有图表。你需要什么更好的解释? 我无法理解。我想要一个广义的证明。 【参考方案1】:

好的,首先,让我们调用形成input 字符串A 的子字符串。所以,

input = A ^ a (with a is constant)

我们可以看到,如果input 是电源字符串,那么最长的专有前缀(也是后缀)应该至少覆盖input 的一半。证明很简单

如果a 是偶数,则情况微不足道。

如果a是奇数,那么input = (A^b)A(A^b),我们可以看到,最长的前缀后缀至少应该是(A^b)A (with b = (a - 1)/2)

所以,现在,让我们考虑三种情况:

如果前缀后缀的长度kk < n/2,那么n - k > n/2 -> n % (n - k) != 0,如上证明,这个字符串不能是幂字符串。

如果前缀后缀的长度kk = n/2 -> 这种情况很简单。

如果前缀后缀的长度kk > n/2,那么,我们可以将输入字符串可视化为

input = ACA

其中C是前缀和后缀的重叠区域,并且由于前缀和后缀相等,我们可以看到

AC = CA 

假设C > A的长度为AC = CA,所以,我们可以将C分成C = A + B -> A + A + B = A + B + A,这只有在A == B时才会发生。

因此,输入将具有input = AAAA 的形式,这显然是一个电源字符串。 在C = A 的情况下,我们有input = AAA,并且可以证明C < A 的情况与C > A 的情况类似。

【讨论】:

【参考方案2】:

如果 n%(n-k) == 0,则字符串可以表示为重复有限次的子字符串。否则,不。这句话对算法很有帮助,所以让我们从证明它开始 如果 n-k 是后缀的长度,那么如果 n%(n-k) != 0 n 将等于长度为 n-k 的 q 字符串和长度小于 n-k 的字符串的串联 (q = n / (n-k)) 所以在这种情况下 n 不能是后缀的平方 反对派领导的推理 现在让我们编写代码

 class Program
    
        static void Main(string[] args)
        
            string myString = "abab";
            int k = suffixLentgth(myString);
            if (k > 0)
            
                Console.WriteLine(myString.Substring(k, myString.Length - k));
            

        
        static int suffixLentgth(string ch)
        
            int n = ch.Length;
            for (int i = 2; i < n; i++)
            
                bool isPower = true;
                if (n % (n - i) == 0) // this suffix can fulfil your dreams
                
                    for (int j = 0; j < (n / (n - i)) - 1; j++)
                    
                        if (ch.Substring((n - i) * j, n - i) != ch.Substring((n - i) * (j + 1), n - i))
                        
                            isPower = false;
                            break;
                        
                    
                    if (isPower)
                        return i;
                
            
            return 0;
        

【讨论】:

以上是关于将字符串表示为子字符串的某种幂的主要内容,如果未能解决你的问题,请参考以下文章

如何在iOS上将字符串拆分为子字符串?

如何查看字符串是不是为子字符串。 Java [重复]

Python:根据索引范围将列表拆分为子列表

在java中将字符串划分为子字符串

KMP算法

python中split的用法分割的字符串怎么命名?