【编程之美】读书笔记:求二进制数中1的个数

         问题:求二进制中1的个数。对于一个字节(8bit)的无符号整型变量,求其二进制表示中"1"的个数,要求算法的执行效率尽可能的高。

        解法一:对于一个八位的二进制数据,除以一个2,原来的数字中将减少一个0.如果除的过程中有余,那么当前位置就有一个二进制位1.

  例如:10100010 

         它第一次除以2,商为1010001,余数为0;它第二次除以2,商为101000,余数为1.

 由上面可得解法一的代码如下:

 int Count(BYTE v)
{
int num=0;
while(v)
{
if(v%2==1)
{
num++;
}
v=v/2;
}
return num;
}

解法二:使用位操作

           这个解法主要在于移位之后如何来判断是否有1的存在。例如:10100001.在向右移动的过程中,会直接丢弃最后一个1.因此需要判断最后一位是否为1,而“与”操作可以达到目的。可以把这个八位的数字与00000001进行与操作,如果结果为1,则表示当前八位数的最后一位是1,否则为0.

代码如下:

 int Count(BYTE v)
{
int num=0;
while(v)
{
num+=v&0x01;
v>>=1;
}
return num;
}         
解法三: 用到一个巧妙的与操作,v & (v -1 )每次与操作能消去二进制表示中最后一位1,通过统计这个的个数即可以,利用这个技巧可以减少一定的循环次数。

int Count(BYTE v)
{
int num=0;
while(v)
{
v&=(v-1);
num++;
}
return num;
}

解法四,查表法,因为只有数据8bit,直接建一张表,包含各个数中1的个数,然后查表就行。复杂度O(1)。

int countTable[256] = { 0, 1, 1, 2, 1, ..., 7, 7, 8 };   
         
     int Count(int v) {   
         return countTable[v];   
   }

 注:查表法的复杂度为O(1),解法一,循环八次固定,复杂度也是O(1)。至于数据规模变大,变成32位整型,那查表法自然也不合适了。

问题二:给定两个整数A和B(二进制表示),问A和B有多少位是不同的。

这个问题其实就是数1问题多了一个步骤,只要先算出A和B的异或结果,然后求这个值中1的个数就行了。



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值