计算基本位字符串

如果一个比特串不是一个较小比特串的多个副本的重复,则称其为基元。例如,101101不是原语,因为它可以分解为字符串101的两个副本。在Python表示法中,可以通过"101"*2另一方面,字符串11001101是基本的。(它包含非原始的子字符串,但字符串作为一个整体不能分解为单个字符串的多个副本。)

对于给定的n个,让我们计算长度有多少个基本位字符串n个。打电话给这个(f)(n个). 有2个n个长度的位串n个、和(f)(n个)这些是原始的。例如,有(f)(12) 长度为12的基本位字符串。非原语字符串由原语字符串的副本组成:两个长度为6的原语字符串副本,三个长度为4的原语串副本,等等。这表示

2^{12}=f(12)+f(6)+f

一般来说

2^n=sum_{d\midn}f(d)

这里的和是所有正整数的和d日那道鸿沟n个.

不幸的是,这个公式是落后的。它给出了一个众所周知的公式,2n个,作为我们试图计算的所有事情的总和。这个莫比乌斯反演公式这正是我们需要改变这个公式的地方,这样新事物就在左边,旧事物的总和就在右边。它告诉我们

f(n)=sum{d\midn}\mu\left(\frac{n}{d}\right)2^d

其中μ是Möbius函数。

我们可以计算(f)(n个)使用Python,如下所示:

来自sympy.theory import mobius,除数定义num_primitive(n):返回和(mobius(n/d)*2**d用于除数(n)中的d)

SymPy的最新版本0.7.6带有一个函数莫比乌斯用于计算Möbius函数。如果您使用的是SymPy的早期版本,您可以使用自己的莫比乌斯功能:

来自sympy.theory进口保理商定义mobius(n):指数=因子(n).values()lenexp=len(指数)m=0,如果lenexp==0 else max(指数)如果m>1,则返回0,否则返回(-1)**lenexp

的版本莫比乌斯SymPy 0.7.6附带的可能更高效。例如,如果发现平方因子,它可以提前停止因子分解过程。

相关的:应用数论

关于“计算基本位字符串

  1. 你也可以重新排列第一个公式,得到f(n)的递归公式。

    2^n=和{f(d),d|n}
    2^n=f(n)+和{f(d),d|n;d<n}
    f(n)=2^n-和{f(d),d|n;d<n}

    基本情况是素数n,其中f(n)只是2^n。

  2. 以下是SymPy代码:

    定义评估(cls,n):如果n.is_integer:如果n.is_positive不为True:raise ValueError(“n应为正整数”)其他:引发TypeError(“n应为整数”)如果n.is_prime:返回S.NegativeOneelif n是S。一:返回S.Oneelif n.is_集成器:a=因子(n)如果有(对于a.values()中的i,i>1):返回S.Zeroreturn S.NegativeOne**长度(a)

    看起来效率不高。据我所知,SymPy的factorint()不支持流因子。这将是一个有用的功能,尽管它只在处理素数因子非常大的数字时才起作用(例如,factorint()中的算法在进入Pollard rho算法之前对素数进行了2^15的试探性除法)。

    SymPy函数的一个优点是它以符号方式工作,也就是说,您可以将符号值放入mobius(n)中,并对其进行操作,然后替换它们

  3. 我认为您的mobius()函数中有一个错误。

    mobius(12)应该为0,但代码返回1

    我认为它不应该查找min(指数),而应该只查找任何(指数>1)。

  4. 几个月前,StackOverflow上有一个关于确定字符串是否原始的问题,但我找不到它。它基本上复制了字符串,并检查了它的所有循环模式,看看是否有重复的。不过,很容易找到他们的号码!

  5. http://oeis.org/A027375“长度为n的非周期二进制字符串的数量;以及基元周期为n的二进制序列的数量”
    0, 2, 2, 6, 12, 30, 54, 126, 240, 504, 990, 2046, 4020, 8190, 16254, 32730, 65280, 131070, 261576, 524286, 1047540, 2097018, 4192254, 8388606, 16772880, 33554400, 67100670, 134217216, 268419060, 536870910, 1073708010, 2147483646, 4294901760

评论已关闭。