您的位置:首页 > 其它

Fast bit count问题(即计算一个unsigned int的二进制表达中1的数目)

2011-06-24 15:24 344 查看
最近在看《Programming Pearls》。里面的好些问题很有意思。做一点小小的总结吧。

这个问题是计算一个unsigned int型二进制数中一个的个数,google中看到了不少很巧妙的算法,在这里做一个简单总结。另外,很喜欢stackoverflow这个论坛,geek很多,打酱油的人很少,感觉国外的程序员遇到有趣的问题兴致更高。关于这个问题,帖子见http://stackoverflow.com/questions/109023/best-algorithm-to-count-the-number-of-set-bits-in-a-32-bit-integer。

直观的想法

最简单最直观的想法是检测每一位是不是1,如果是的话就计数器加1,最后肯定能得出结果来。虽然"too simple, sometimes naive",但是一般情况下是很好用的,需要的时候不用到处查,很快就能写出来。

int NumberOfSetBits(unsigned int n)
{
int c = 0;
for(int j = 0; j <32; j++)
{
if(n & (1<<j))
{
c++;
}
}
return c;
}


下面的程序思路一样,也是每位检测:

unsigned int bitCount (unsigned int value) {
unsigned int count = 0;
while (value > 0) {           // until all bits are zero
if ((value & 1) == 1) {   // check lower bit
count++;
}
value /= 2;               // shift bits, removing lower bit
}
return count;
}


进阶

下面的这种方法比较巧妙,已经比较难想到了。可以动手试试n-1的二进制表达就明白了。

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;
}


高级

这里面的方法属于那种“此曲只应天上有”的类型,我都没有尝试去理解,用的时候查一下就好了。

int pop(unsigned x)
{
x = x - ((x >> 1) & 0x55555555);
x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
x = (x + (x >> 4)) & 0x0F0F0F0F;
x = x + (x >> 8);
x = x + (x >> 16);
return x & 0x0000003F;
}


最懒的方法


下面的程序只有一句话,调用系统库函数

__builtin_popcount,我在gcc下编译运行是可以的。


int __builtin_popcount (unsigned int x);




内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐