This repository has been archived by the owner on Aug 23, 2023. It is now read-only.
/
SetBits.cs
75 lines (64 loc) · 2.51 KB
/
SetBits.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CS.Problems.BitManipulation
{
/// <summary>
/// Problem details below
/// http://www.geeksforgeeks.org/count-total-set-bits-in-all-numbers-from-1-to-n/
/// https://stackoverflow.com/questions/9812742/finding-the-total-number-of-set-bits-from-1-to-n
/// </summary>
public class SetBits
{
public static int Count(int integer)
{
//base case
//zero set bits in zero
if (integer == 0)
{
return 0;
}
//any integer will be = 2 ^ b + 2 ^ b-1 + 2^ b -2 ....+ 2 ^ 0 + 0
//where b is the MSB exponent
var b = FindLeftMostSetBitPosition(integer);
//if integer is 1, 3, 7, 15, 31 etc
//if integer is of the form (2^b)-1 where b = 0, 1, 2 .. (exponents)
//eg. integer = 3 (011), position = 1 => 3 + 1 == (1<<(1+1)) => 4 == 4 (100)
if (integer + 1 == (int)Math.Pow(2, b))
{
//based on the observation
//if integer is of the form (2^b)-1 where b = 0, 1, 2 .. (exponents)
//for example the numbers 1, 3, 7, 15, 31 etc
//then BitCount = b * 2^(b-1)
//eg integer => 3, position => 1 => 2 * 2^1 => 4
return (b + 1) * (int)Math.Pow(2, b);
}
//based on the observation
//if integer is of the form (2^b)-1 where b = 0, 1, 2 .. (exponents)
//for example the numbers 1, 3, 7, 15, 31 etc
//then BitCount = b * 2^(b-1)
//eg Count(3) = 4
var msbSetBitCount = b * (int)Math.Pow(2, b - 1);
//now compute the bitCount for remaining balance
var balance = integer - (int)Math.Pow(2, b);
//again another observation is that
//count for balance will equal to Count(balance) + (balance + 1)
//Count(6) = Count(3) + remaining bit count
//Count(6) = 4 + Count(2) + (2 + 1)
//Count(6) = 4 + (1 + 0 + 1) + 2 + 1 = 9
return msbSetBitCount + Count(balance) + (balance + 1);
}
public static int FindLeftMostSetBitPosition(int integer)
{
int count = 0;
while (integer > 0)
{
integer = integer >> 1;
count++;
}
return count - 1;
}
}
}