【编程之美】读书笔记:求二进制数中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的个数就行了。

    原文作者:xiaoding133
    原文地址: https://blog.csdn.net/xiaoding133/article/details/8034899
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞