我怎样才能得到 “1”的个数 以数字的二进制表示形式而不实际转换和计数?

例如

  def number_of_ones(n):
      # do something
      # I want to MAKE this FASTER (computationally less complex).
      c = 0
      while n:
        c += n%2
        n /= 2
      return c


>>> number_of_ones(5)
    2
>>> number_of_ones(4)
    1
有帮助吗?

解决方案

IMO,一个好的办法是使用查表 - 创建它转换字节数的字典1的(你可以用你发布到生成它的代码,那就只需要运行一次),和然后使用这样的:

def number_of_ones(n):
    sum = 0
    while n != 0:
        sum += lookup_table[n & 0xff]
        n >>= 8
    return sum

我相信这是一个相当不错的折衷空间和运行时间之间。

其他提示

我不是一个Python程序员,但希望这将是足以让你跟着。

c = 0
while n:
    c += 1
    n &= n - 1

return c

虽然有点模糊,这是主要的优点是速度和简便性。 while循环仅针对每一个位在将n设置为1迭代一次。

您不能让这种计算那么复杂。这将是O(n)的比特数,或者,与&特技显示了答案,为O(n)设定为1的位的数目;但除非所有正在使用的数字是一个特殊的情况下,后者应在平均为n / 2,因此这两个的O(n)的数字是相同的。

和查找表绝招,当然,实际上什么都不做了计算复杂度;它只是支付的时间与空间,但不改变基本经济状况,这是您必须一次检查每个位的不知何故的并有周围没有办法。你不能在逻辑上,回答关于在数位的问题,而不检查它们中的每

现在,我想我是一个有点草率,因为许多这样的例子实际上是为O(n ^ 2),因为在Python中,你必须检查整个号在一次时间,所以用一个Python长整型,说,100个字节,一个+或&或/操作将着眼于每个字节至少一次,并且直到数量减少到零(在上文所概述的方案),将反复发生,所以这些,同样,是真正为O(n ^ 2)操作。我不知道Python会允许一个真正为O(n)解决方案在这里。

总之:如果你真的问的计算的复杂性,具体是指大O分析中,这就是你的答案。 : - )

如果你想这样做在一个单一的线,你可以使用:

sum( [x&(1<<i)>0 for i in range(32)] )

如果您确实关心速度,请用 C 编写代码(请参阅 这个问题 了解如何实现),并使用类似的方式与 C 实现进行交互 c类型.

下面:

DEF比特计数(int_no):

c = 0
while(int_no):
    int_no &= (int_no - 1)
    c += 1
return c

这可能是一个古老而有效的方式做到这一点...原来用C implementated(算法中有我不记得名字)。我希望它正常工作,它为任何其他人

P =拉姆达N:N和1个+ P(N&第(n-1))

此使用短路和递归,当n大于0,则它切换到计算1个+ P(N&第(n-1))时,其中P(N&第(n-1))被称为等, n为0则返回0复杂度为O(N),因为它运行在二元存在一的数量的次数。

例:P(9)= 1 + P(8)= 1 + 1个+ P(0)= 1 + 1 + 0 = 2

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top