Finding the total number of set-bits from 1 to n

后端 未结 16 1950
轻奢々
轻奢々 2020-12-04 09:54

Write an algorithm to find F(n) the number of bits set to 1, in all numbers from 1 to n for any given value of n.

Complexity should be O(log n)

相关标签:
16条回答
  • 2020-12-04 10:21

    this is coded in java...
    logic: say number is 34, binary equal-ant is 10010, which can be written as 10000 + 10. 10000 has 4 zeros, so count of all 1's before this number is 2^4(reason below). so count is 2^4 + 2^1 + 1(number it self). so answer is 35.
    *for binary number 10000. total combinations of filling 4 places is 2*2*2*2x2(one or zero). So total combinations of ones is 2*2*2*2.

    public static int getOnesCount(int number) {
        String binary = Integer.toBinaryString(number);
        return getOnesCount(binary);
    }
    
    private static int getOnesCount(String binary) {
        int i = binary.length();
    
        if (i>0 && binary.charAt(0) == '1') {
            return gePowerof2(i) + getOnesCount(binary.substring(1));
        }else if(i==0)
            return 1;
        else
            return getOnesCount(binary.substring(1));
    
    }
    //can be replaced with any default power function
    private static int gePowerof2(int i){
        int count = 1;
        while(i>1){
            count*=2;
            i--;
        }
        return count;
    }
    
    0 讨论(0)
  • 2020-12-04 10:21
    x = int(input("Any number:\n"))
    y = (bin(x))
    print(y)
    v = len(y) -2
    print(v)
    
    0 讨论(0)
  • 2020-12-04 10:25

    Here is the java function

    private static int[] findx(int i) {
        //find the biggest power of two number that is smaller than i
        int c = 0;
        int pow2 = 1;
        while((pow2<< 1) <= i) {
            c++;
            pow2 = pow2 << 1;
        }
        return new int[] {c, pow2};
    }
    
    public static int TotalBits2(int number) {
        if(number == 0) {
            return 0;
        }
        int[] xAndPow = findx(number);
        int x = xAndPow[0];
        return x*(xAndPow[1] >> 1) + TotalBits2(number - xAndPow[1]) + number - xAndPow[1] + 1;
    }
    
    0 讨论(0)
  • 2020-12-04 10:27

    By the way, this question can also be done by the method of lookup table. Precompute the number of set bits from 0-255 and store it. Post that, we can calculate the number of set bits in any number by breaking a given number into two parts of 8 bits each. For each part, we can lookup in the count array formed in the first step. For example, if there is a 16 bit number like,

    x = 1100110001011100, here, the number of set bits = number of set bits in the first byte + number of set bits in the second byte. Therefore, for obtaining, first byte,

    y = (x & 0xff) z = (x >> 8) & (0xff) total set bits = count[y] + count[z]

    This method will run in O(n) as well.

    0 讨论(0)
  • 2020-12-04 10:28
    int countSetBits(int n)
    {
        n++;
        int powerOf2 = 2;
        int setBitsCount = n/2;
        while (powerOf2 <= n)
        {
            int numbersOfPairsOfZerosAndOnes = n/powerOf2;
            setBitsCount += (numbersOfPairsOfZerosAndOnes/2) * powerOf2;
            setBitsCount += (numbersOfPairsOfZerosAndOnes&1) ? (n%powerOf2) : 0;
            powerOf2 <<= 1;
        }
        return setBitsCount;
    }
    

    Please check my article on geeksforgeeks.org for detailed explanation. Below is the link of the article https://www.geeksforgeeks.org/count-total-set-bits-in-all-numbers-from-1-to-n-set-2/

    0 讨论(0)
  • 2020-12-04 10:29

    short and sweet!

     public static int countbits(int num){
        int count=0, n;
        while(num > 0){
            n=0;
            while(num >= 1<<(n+1))
                n++;
            num -= 1<<n;
            count += (num + 1 + (1<<(n-1))*n);
        }
        return count;
    }//countbis
    
    0 讨论(0)
提交回复
热议问题