使用具有无限存储器的K& R方法计算比特数

时间:2010-08-18 10:30:45

标签: algorithm bit-manipulation

我得到了这个问题的答案,从这里计算一组位数。

How to count the number of set bits in a 32-bit integer?

long count_bits(long n) {      
  unsigned int c; // c accumulates the total bits set in v 
  for (c = 0; n; c++)  
    n &= n - 1; // clear the least significant bit set 
  return c; 
} 

也很容易理解。并找到了最好的答案,作为Brian Kernighans的方法,由hoyhoy发布......并且他在最后添加了以下内容。

请注意,这是访问期间使用的问题。面试官会加上你有“无限记忆”的警告。在这种情况下,您基本上创建一个大小为232的数组,并填写每个位置的数字位数。然后,该函数变为O(1)。

有人可以解释一下如何做到这一点吗?如果我有无限的记忆......

2 个答案:

答案 0 :(得分:2)

我见过填充这样一个数组的最快方法是......

array[0] = 0;
for (i = 1; i < NELEMENTS; i++) {
    array[i] = array[i >> 1] + (i & 1);
}

然后计算给定数字中的设定位数(假设给定数字小于NELEMENTS)......

numSetBits = array[givenNumber];

如果你的内存不是有限的,我经常会看到NELEMENTS设置为256(一个字节值),并在整数的每个字节中添加设置位数。

答案 1 :(得分:0)

int counts[MAX_LONG];

void init() {
   for (int i= 0; i < MAX_LONG; i++)
   {
       counts[i] = count_bits[i]; // as given
   }
}


int count_bits_o1(long number)
{
   return counts[number];
}

你可以更加明智地预先填充数组,即填充零,然后每隔一个索引添加一个,然后每四个索引添加1,然后每八个索引添加1等,可能有点快,虽然我对此表示怀疑......

此外,您可能会考虑无符号值。