📌  相关文章
📜  使用查找表对整数中的设置位进行计数

📅  最后修改于: 2021-04-29 11:55:44             🧑  作者: Mango

编写一个有效的程序,以整数的二进制表示形式计算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)