[编程之美2.1]求二进制数中1的个数

来源:互联网 发布:苏联解体武汉会战 知乎 编辑:程序博客网 时间:2024/06/04 18:23

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

思路一:从十进制转化为二进制的方法中获得启发,可以余2然后判断是否为一,是则加一,再将该数除2继续之前的判断操作。
思路二:将余2和除2操作用位操作&和>>来表示,使得效率更加快
思路三:判断一个数是否为2的幂次可以用v&(v - 1)来求解,比如v = 1000000,则v-1 = 0111111,此时v与v-1所有位上的数都不相同,显然可以用v&(v-1)是否为0来判断v是否为                 2的幂次,根据此思路,可以算出1的位数,复杂度是该数中1的个数
思路四:用空间换时间的策略,8字节的变量,总共也就128个数,将这128个结果列成一个数组直接打出来即可,然后可以根据索引求值

扩展问题:
1  如果变量是32位的DWORD,你会使用上述的哪一个方法,或者改进哪一个算法?
2 另一个相关的问题,给定两个正整数(二进制形式表示)A和B,问把A变为B需要改变多少位?也就是说,整数A和B的二进制表示中有多少位是不同的?

扩展问题解答:
1 当32位的时候,使用方法3是最明智的选择
2 看两个数:a = 100,b = 101,可以看到位操作数里有异或 “^”,位数不同的时候,就显示为1,a ^ b = 100 ^ 101 = 001,有一位为1,1的个数则代表了多少位的不同,这个可以用上述的方法求得。

代码如下:

#include <iostream>#include <stdlib.h>using namespace std;int countOne_1(int num){int sum = 0;while(num){if(num % 2 == 1)sum++;num /= 2;}return sum;}int countOne_2(int num){int sum = 0;while(num){sum += num &0x01;num >>= 1;}return sum;}int countOne_3(int num){int sum = 0;while(num){num &= (num - 1);sum++;}return sum;}int main(){cout << countOne_1(3) << endl;cout << countOne_2(7) << endl;cout << countOne_3(127) << endl;system("pause");return  0;}

原创粉丝点击