种群计数-位计数

前言:

  这是一篇位运算相关的文章,问题只有一个,统计一个数,它的2进制表示中1的个数。

  这道题大家应该都见过,《编程之美-微软技术面试心得》一书中有相关的章节。

  不说废话~

正题来了:

  算法一:

1 count = 0;
2 for(i = 0;i < 32;i++)
3 {
4     if(x&1)  count ++;
5     x = x >> 1;
6 }

  对整数2进制表示的每一位进行位&运算,判断是否为1,是的话计数器count+1;

  算法二:

1 count = 0;
2 for(i = 0;i < 32;i++)
3 {
4     count += (x & 1);
5     x = x >> 1;
6 }

  算法二是对算法一的优化,少了if的判断,还是渣;

  算法三:

1 count = 0;
2 while(x)
3 {
4     count ++;
5     x = x & (x-1);
6 }

  这是个好算法:x&(x-1),析出x最右边的1;

  每循环一次相当于x的二进制表示最右边的1变成了0;

  直到x的值为0,代表所有的1都析出;

  算法四:

  

1 int count = 0;
2 int size[] = {0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4};
3 while(x)
4 {
5     count += size[x&0xF];
6     x = x>>4;
7 }

  采用查表法,每4位一查,效率也是很快的;

  算法五:(重头戏)

  

1 x = (x & 0x55555555) + ((x >> 1) & 0x55555555)
2 x = (x & 0x33333333) + ((x >> 2) & 0x33333333)
3 x = (x & 0x0F0F0F0F) + ((x >> 4) & 0x0F0F0F0F0F)
4 x = (x & 0x00FF00FF) + ((x >> 8) & 0x00FF00FF)
5 x = (x & 0x0000FFFF) + ((x >> 16) & 0x0000FFFF)

  最后的x值为1的个数;

  这是一个“分治”策略的例子,在原始问题上(对32个位求和)被分成两个问题(对16个位求和),递归运用这一策略,直到对1个位求和;

  后记:

  还有问题的请研究《高效程序的奥秘》

  一本致力于位运算的好书

posted on 2013-04-12 18:32  Z-fadeaway  阅读(471)  评论(0编辑  收藏  举报