【问题标题】:count the number of binary string of length n that is repeatable计算可重复的长度为 n 的二进制字符串的数量
【发布时间】:2016-08-10 14:59:25
【问题描述】:

问题是求长度为n的可重复二进制串的个数。如果二进制串的任意一个子串可以重复自身形成原始二进制串,则该二进制串是可重复的。

Example
"1010" is a repeatable string as it can be obtained from "10" by repeating 2 number of times

"1001" is  not a repeatable string as it cannot be obtained from any sub string of "1001" by repeating them any number of times

我想到的解决方案是生成所有可能的长度为n的二进制字符串,并使用KMP算法检查它是否是可重复的,但是即使对于像n = 40这样的小n,这种解决方案也不可行。

我认为的第二种方法是

  1. 对于 n 的除数 k,找到所有长度为 k 且重复 n/k 次的子字符串

例如 n = 6 我们有除数 1,2,3

对于长度 1,我们有 2 个重复的子字符串“1”和“0” 6 所以“111111”和“000000”是可重复的字符串

对于长度 2,我们有 4 个子字符串 "00" "01" "10" "11" 所以 "000000" "010101" "101010" 和 "111111" 是可重复的字符串

对于长度为 3 的类似,我们有 8 个可重复的字符串。

  1. 将所有除数生成的字符串相加并减去重复项。

在上面的例子中,字符串“111111”和“000000”对于每个除数都被计算了 3 次。所以很明显我是在计数。我需要减去重复项,但无论如何我都想不出从中减去重复项我的实际计数我该怎么做?

我是朝着正确的方向前进还是需要采取其他方法?

【问题讨论】:

  • 您当前的方法对我来说看起来不错。要弄清楚如何避免两次计算字符串,最好查看(例如 Wikipedia 文章)Inclusion-Exclusion Principle。

标签: string algorithm combinatorics counting


【解决方案1】:

当您使用第二种方案时,删除由可重复二进制文件组成的子字符串。例如,00 和 11 分别由 0 和 1 的重复组成。所以长度为 2 只考虑“01”和“10” 长度为 3 只考虑“001”、“010”、“011”、“100”、“101”、“110” ... 一般来说, 对于 n 的奇数长度,删除 0 和 (2^n)-1, 对于 n 的偶数长度,删除 0, (2^(n/2)+1), (2^(n/2)+1)2, ...., (2^n)-1 如果 n 可以被 3 整除,则 (1+2^(n/2)+2^(n-2)), (1+2^(n/2)+2^(n-2)) 2、... 对所有分隔线继续此操作。

【讨论】:

    【解决方案2】:

    一个想法是,如果我们只计算从非重复子字符串生成除数大小的字符串的方法,则除数的除数的计数将说明从重复子字符串生成除数的方法。

    f(1) = 0
    f(n) = sum(2^d - f(d)), where 1 <= d < n and d divides n
    

    ...意思是只有n的除数不能由重复子串组成的方式的总和。

    f(2) = 2^1-0
    f(3) = 2^1-0
    f(4) = 2^1-0 + 2^2-2
    f(6) = 2^1-0 + 2^2-2 + 2^3-2
    ...
    

    【讨论】:

      猜你喜欢
      • 2016-02-18
      • 2011-12-04
      • 2016-01-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多