简体   繁体   English

如何统计数字的总设置位数

[英]How to count the total number of set bits for the number

  • Given a positive integer A, the task is to count the total number of set bits in the binary representation of all the numbers from 1 to A.给定一个正数 integer A,任务是计算从 1 到 A 的所有数字的二进制表示中设置位的总数。
 A = 3
 DECIMAL    BINARY  SET BIT COUNT
    1          01        1
    2          10        1
    3          11        2

1 + 1 + 2 = 4

  • I got correct output我得到正确的 output

Code is below代码如下

def solve(A):
     ad = ''
     for i in range(A + 1):
         ad += str(bin(i).replace('ob',''))
     return ad.count('1')

With Bit-wise按位

  def solve(A):
        count = 0
        for i in range(A + 1):
            while i > 0:
                i= i & (i-1)
                count += 1
        return (count)
  • In both scenarios I am getting Time Limit Exceeded.在这两种情况下,我都Time Limit Exceeded.

This would work in O(log(A)) so you shouldn't have Time Limit Exceeded:这将在 O(log(A)) 中工作,所以你不应该超过时间限制:

def solve(A):
  count = 0
  n = A
  i = 0
  while n > 0:
    if (n & 1) == 1:
      f = ((1 << i) >> 1) * i
      g = (((1 << i) - 1) & A) + 1
      count += f + g
    n >>= 1
    i += 1
  return count

The total number of set bits between 0 and 2^n excluded is 2^(n-1)*n.排除在 0 和 2^n 之间的设置位总数为 2^(n-1)*n。 Because in this particular case, 50% of bits are set in each column and other 50% are unset, and there is n columns.因为在这种特殊情况下,每列中设置了 50% 的位,其他 50% 未设置,并且有 n 列。

For a number A which is not a power of 2, we can break down the calculation into several passes, one for each set bit in the number A in question, and use the expression for exact power of 2 (variable f).对于不是 2 的幂的数字 A,我们可以将计算分解为几遍,一次针对所讨论的数字 A 中的每个设置位,并使用 2 的精确幂(变量 f)的表达式。 We must also take care of an additional column of 1 each time (variable g).我们还必须每次都处理一个额外的 1 列(变量 g)。

Schema to see why it works架构以了解其工作原理

I was working on a solution similar to covstag's one, but my way of calculating the sum of bits set for a power of 2 was definitely clumsier.我当时正在研究一种类似于 covstag 的解决方案,但我计算 2 的幂的位总和的方法肯定比较笨拙。 So I stole the idea and adapted it to my solution;所以我偷了这个想法并将其改编为我的解决方案; the result is just slightly faster, but perhaps easier to understand:结果只是稍微快一点,但也许更容易理解:

def solve(A):
    loop = 0
    current = 0
    bits = f'{A:b}'
    expo = len(bits) - 1
    for b in bits[:-1]:
        if b == '1':
            power = 2**(expo-1)
            current += expo * power + 1 + 2 * power * loop
            loop += 1
        expo -= 1
    if bits[-1] != '0':
        current += loop + 1
    return current

This would work:这会起作用:

def solve(A):
    return sum(int(b) for n in range(1, A + 1) for b in f"{n:b}" if b == '1')

This is another, very classic, way:这是另一种非常经典的方式:

def solve(A):
    result = 0
    for n in range(1, A + 1):
        while n > 0:
            result += n % 2
            n //= 2
    return result 

In yours first solution, you can improve it a little:在您的第一个解决方案中,您可以稍微改进一下:

def solve(A):
    result = 0
    for i in range(A + 1):
         result += bin(i).count('1')
    return result

or even to甚至

def solve(A):
    return sum(bin(i + 1).count('1') for i in range(A))

which is similar to my first attempt, maybe even better.这与我的第一次尝试相似,甚至可能更好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM