📜  计算从1到n的所有数字中的总置位数|套装2

📅  最后修改于: 2021-05-25 08:01:49             🧑  作者: Mango

给定正整数N ,任务是对从1N的所有数字的二进制表示形式中的设置位数的总和进行计数。
例子:

方法:这里讨论了解决此问题的其他方法。在本文中,讨论了另一种具有时间复杂度O(logN)的方法。
检查下表中从1到N的数字的二进制表示形式:

Decimal Binary Set Bit Count
1 01 1
2 10 1
3 11 2

请注意,

  1. A中的每个备用位都被置位。
  2. B中的每2个备用位被置1。
  3. C中的每4个备用位被置1。
  4. D中的每8个备用位被置1。
  5. …..
  6. 这将继续以每2的幂次重复。

因此,我们将迭代直到数字中的位数。而且,我们不必迭代从1到n范围内的每个数字。
我们将执行以下操作以获得所需的结果。

  • ,首先,我们将数字加1以补偿0。由于二进制数系统从0开始。所以现在n = n + 1。
  • 到目前为止,我们将跟踪遇到的设置位的数量。我们将用n / 2对其进行初始化。
  • 我们将保留一个2的幂的变量,以便跟踪我们正在计算的位。
  • 我们将迭代直到2的乘方大于n。
  • 我们可以通过将n除以当前2的幂来获得所有数字的当前位中0和1s的对数。
  • 现在我们必须在设置的位数中添加位数。我们可以通过将0和1s的对数除以2来做到这一点,这将仅给我们1s的对数,然后,我们将其乘以2的当前幂以得到组中1的个数。
  • 现在可能有机会获得成对的数字,该数字在组的中间位置,即1的数量小于该特定组中2的当前乘方。因此,我们将找到模数并将其添加到设置位的计数中,借助示例可以清楚地看出这一点。

示例:考虑N = 14
在上表中,共有28个设置位,从1到14。
我们将2 0视为A,将2 1视为B,将2 2视为C,将2 3视为D
首先我们将数字N加1,所以现在我们的N = 14 +1 = 15。

  • A的计算(2 0 = 1)
    15/2 = 7
    A = 7的置位位数————>(i)
  • B的计算(2 ^ 1 = 2)
    15/2 = 7 =>有7组0和1
    现在,仅计算设置位的组数,我们必须将其除以2。
    因此,7/2 =3。有3个设置位组。
    并且这些组这次将包含等于2的幂的设置位,即2。因此,我们将设置位组的数量乘以2的幂
    => 3 * 2 = 6->(2i)

    可能会有一些额外的1,因为未考虑第4组,因为该除法将只给我们整数值。因此,我们也必须添加它。注意:–仅当0和1的组数为奇数时,才会发生这种情况。
    15%2 = 1->(2ii)
    2i + 2ii => 6 +1 = 7 ————>(ii)
  • C的计算(2 ^ 2 = 4)
    15/4 = 3 =>有3组0和1
    设置位组的数量= 3/2 = 1
    这些组中的置位位数= 1 * 4 = 4 —>(3i)
    由于3为奇数,因此我们必须在未考虑的组中添加位
    因此,15%4 = 3->(3ii)
    3i + 3ii = 4 + 3 = 7 ————>(iii)
  • D的计算(2 ^ 3 = 8)
    15/8 = 1 =>有1组0和1。现在,在这种情况下,只有一个组,也只有0个组。
    设置的位组数= 1/2 = 0
    这些组中的置位位数= 0 * 8 = 0 —>(4i)
    由于组数是奇数,
    因此,15%8 = 7->(4ii)
    4i + 4ii = 0 + 7 = 7 ————>(iv)

此时,我们2的幂次幂变得大于数字,在本例中为15。 (2的幂= 16且16> 15)。因此,循环在此处终止。
最终输出= i + ii + iii + iv = 7 + 7 + 7 + 7 = 28
从1到14的设置位数为28。
下面是上述方法的实现:

C++
// C++ implementation of the approach
#include 
using namespace std;
 
// Function to return the sum of the count
// of set bits in the integers from 1 to n
int countSetBits(int n)
{
 
    // Ignore 0 as all the bits are unset
    n++;
 
    // To store the powers of 2
    int powerOf2 = 2;
 
    // To store the result, it is initialized
    // with n/2 because the count of set
    // least significant bits in the integers
    // from 1 to n is n/2
    int cnt = n / 2;
 
    // Loop for every bit required to represent n
    while (powerOf2 <= n) {
 
        // Total count of pairs of 0s and 1s
        int totalPairs = n / powerOf2;
 
        // totalPairs/2 gives the complete
        // count of the pairs of 1s
        // Multiplying it with the current power
        // of 2 will give the count of
        // 1s in the current bit
        cnt += (totalPairs / 2) * powerOf2;
 
        // If the count of pairs was odd then
        // add the remaining 1s which could
        // not be groupped together
        cnt += (totalPairs & 1) ? (n % powerOf2) : 0;
 
        // Next power of 2
        powerOf2 <<= 1;
    }
 
    // Return the result
    return cnt;
}
 
// Driver code
int main()
{
    int n = 14;
 
    cout << countSetBits(n);
 
    return 0;
}


Java
// Java implementation of the approach
class GFG
{
 
// Function to return the sum of the count
// of set bits in the integers from 1 to n
static int countSetBits(int n)
{
 
    // Ignore 0 as all the bits are unset
    n++;
 
    // To store the powers of 2
    int powerOf2 = 2;
 
    // To store the result, it is initialized
    // with n/2 because the count of set
    // least significant bits in the integers
    // from 1 to n is n/2
    int cnt = n / 2;
 
    // Loop for every bit required to represent n
    while (powerOf2 <= n)
    {
 
        // Total count of pairs of 0s and 1s
        int totalPairs = n / powerOf2;
 
        // totalPairs/2 gives the complete
        // count of the pairs of 1s
        // Multiplying it with the current power
        // of 2 will give the count of
        // 1s in the current bit
        cnt += (totalPairs / 2) * powerOf2;
 
        // If the count of pairs was odd then
        // add the remaining 1s which could
        // not be groupped together
        cnt += (totalPairs % 2 == 1) ?
                      (n % powerOf2) : 0;
 
        // Next power of 2
        powerOf2 <<= 1;
    }
 
    // Return the result
    return cnt;
}
 
// Driver code
public static void main(String[] args)
{
    int n = 14;
 
    System.out.println(countSetBits(n));
}
}
 
// This code is contributed by Princi Singh


Python3
# Python3 implementation of the approach
 
# Function to return the sum of the count
# of set bits in the integers from 1 to n
def countSetBits(n) :
 
    # Ignore 0 as all the bits are unset
    n += 1;
 
    # To store the powers of 2
    powerOf2 = 2;
 
    # To store the result, it is initialized
    # with n/2 because the count of set
    # least significant bits in the integers
    # from 1 to n is n/2
    cnt = n // 2;
 
    # Loop for every bit required to represent n
    while (powerOf2 <= n) :
 
        # Total count of pairs of 0s and 1s
        totalPairs = n // powerOf2;
 
        # totalPairs/2 gives the complete
        # count of the pairs of 1s
        # Multiplying it with the current power
        # of 2 will give the count of
        # 1s in the current bit
        cnt += (totalPairs // 2) * powerOf2;
 
        # If the count of pairs was odd then
        # add the remaining 1s which could
        # not be groupped together
        if (totalPairs & 1) :
            cnt += (n % powerOf2)
        else :
            cnt += 0
 
        # Next power of 2
        powerOf2 <<= 1;
 
    # Return the result
    return cnt;
 
# Driver code
if __name__ == "__main__" :
 
    n = 14;
 
    print(countSetBits(n));
 
# This code is contributed by AnkitRai01


C#
// C# implementation of the approach
using System;
     
class GFG
{
 
// Function to return the sum of the count
// of set bits in the integers from 1 to n
static int countSetBits(int n)
{
 
    // Ignore 0 as all the bits are unset
    n++;
 
    // To store the powers of 2
    int powerOf2 = 2;
 
    // To store the result, it is initialized
    // with n/2 because the count of set
    // least significant bits in the integers
    // from 1 to n is n/2
    int cnt = n / 2;
 
    // Loop for every bit required to represent n
    while (powerOf2 <= n)
    {
 
        // Total count of pairs of 0s and 1s
        int totalPairs = n / powerOf2;
 
        // totalPairs/2 gives the complete
        // count of the pairs of 1s
        // Multiplying it with the current power
        // of 2 will give the count of
        // 1s in the current bit
        cnt += (totalPairs / 2) * powerOf2;
 
        // If the count of pairs was odd then
        // add the remaining 1s which could
        // not be groupped together
        cnt += (totalPairs % 2 == 1) ?
                      (n % powerOf2) : 0;
 
        // Next power of 2
        powerOf2 <<= 1;
    }
 
    // Return the result
    return cnt;
}
 
// Driver code
public static void Main(String[] args)
{
    int n = 14;
 
    Console.WriteLine(countSetBits(n));
}
}
 
// This code is contributed by 29AjayKumar


Javascript


输出:
28