编写一个有效的程序,以整数的二进制表示形式计算1的数量。
例子
Input : n = 6
Output : 2
Binary representation of 6 is 110
and has 2 set bits
Input : n = 13
Output : 3
Binary representation of 11 is 1101
and has 3 set bits
在上一篇文章中,我们看到了在O(log n)时间内解决此问题的不同方法。在这篇文章中,我们使用查找表在O(1)中求解。在这里,我们假设INT的大小为32位。使用查找表很难一次性计算所有32位(“,因为创建大小为2 32 -1”的查找表是不可行的)。因此,我们将32位分解为8位块(通过大小为(2 8 -1)索引的查找表:0-255)。
查找表
在查找故事中,我们存储每个set_bit的计数
范围内的数字(0-255)
LookupTable [0] = 0 |二进制00000000 CountSetBits 0
LookupTable [1] = 1 |二进制00000001 CountSetBits 1
LookupTable [2] = 1 |二进制00000010 CountSetBits 1
LookupTanle [3] = 2 |二进制00000011 CountSetBits 2
LookupTable [4] = 1 |二进制00000100 CountSetBits 1
等等…直到LookupTable [255]。
让我们举个例子,查找表是如何工作的。
Let's number be : 354
in Binary : 0000000000000000000000101100010
Split it into 8 bits chunks :
In Binary : 00000000 | 00000000 | 00000001 | 01100010
In decimal : 0 0 1 98
Now Count Set_bits using LookupTable
LookupTable[0] = 0
LookupTable[1] = 1
LookupTable[98] = 3
so Total bits count : 4
// c++ count to count number of set bits
// using lookup table in O(1) time
#include
using namespace std;
// Generate a lookup table for 32 bit integers
#define B2(n) n, n + 1, n + 1, n + 2
#define B4(n) B2(n) \, B2(n + 1), B2(n + 1), B2(n + 2)
#define B6(n) B4(n) \, B4(n + 1), B4(n + 1), B4(n + 2)
// Lookup table that store the reverse of each table
unsigned int lookuptable[256] = { B6(0), B6(1), B6(1), B6(2) };
// function countset Bits Using lookup table
// ans return set bits count
unsigned int countSetBits(int N)
{
// first chunk of 8 bits from right
unsigned int count = lookuptable[N & 0xff] +
// second chunk from right
lookuptable[(N >> 8) & 0xff] +
// third and fourth chunks
lookuptable[(N >> 16) & 0xff] +
lookuptable[(N >> 24) & 0xff];
return count;
}
int main()
{
// generate lookup table
for (int i = 0; i < 256; i++)
lookuptable[i] = (i & 1) + lookuptable[i / 2];
unsigned int N = 354;
cout << countSetBits(N) << endl;
return 0;
}
输出:
4
时间复杂度:O(1)