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)
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;
}
x = int(input("Any number:\n"))
y = (bin(x))
print(y)
v = len(y) -2
print(v)
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;
}
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.
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/
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