如何在不转换为二进制的情况下检查汉明权重?
-
20-08-2019 - |
题
我怎样才能得到 “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)] )
下面:
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