求二进制数中1的个数
对于一个字节的无符号整形变量,求其二进制数中1的个数,要求算法的执行效率尽量高。
解法一:求余法
每次将该数字除以2,根据求的的余数判断这个位置是不是1.
这样的代码不够简单。
解法二:使用位操作实现解法一的算法
解法三:使用与操作
解法四:穷举法,将0到256这个数的各个位的1的个数存储在一个数组中,调用的时候直接返回这个个数。只需O(1)的时间复杂度。
代码如下:
#include <iostream> using namespace std; //全局变量数组 int countTable[256]= { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6,6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 }; #define BYTE unsigned char /*模2根据结果是否为0来判断,效率为:代码看起来不直观*/ int Count1(BYTE v) { int num=0; //二进制位的个数 while(v) { if(v%2==1) { num++; } v=v/2; //相当于右移一位 } return num; } /*根据移位,然后和0x01与来判断最后一位是否为1,位操作比除,余操作效率高很多*/ int Count2(BYTE v) { int num=0; while(v) { num+=v&0x01; v>>=1; } return num; } int Count3(BYTE v) { int num=0; while(v) { v&=(v-1); num++; } return num; } int Count4(BYTE v) { return countTable[v]; } int main() { cout << "测试主程序" << endl; int v=65; cout<<Count1(v)<<" "<<Count2(v)<<" "<<Count3(v)<<" "<<Count4(v)<<endl; return 0; }