1. 简述
对一个字节(8bit)的无符号整型变量,求其二进制表示中“1”的个数,要求算法的执行效率尽可能的高。
下面是各种解法以及优缺点:
//对于一个BYTE(8位) 变量二进制形式中找出1的个数
//解法一:利用i%2判定是否为1即可
int findOneNum(BYTE i)
{
int count = 0;
while(i){
if(i%2 == 1)
count++;
i=i/2;
}
return count;
}
//解法二:由于取余和除操作效率不高,考虑最后一位是否为1可以让i&00000001即可判定,位操作快多了
int findOneNum(BYTE i)
{
int count = 0;
while(i){
count += (i & 0x01);
i=i>>1;
}
return count;
}
//解法三:前两种方法均为逐位计算的方法,下面可以考虑如何只需要算出1的个数就行了,不管1在哪一个位置。
// 如何判断i只有一个1?考虑1000,只需要考虑1000是否为2的幂即可,可以1000&(1000-1)=0即消除了一个1
int findOneNum(BYTE i)
{
int count = 0;
while(i){
i&=(i-1);
count++;
}
return count;
}
//解法四:查表法---建立i它对应1的个数表格int countTable[256],只需要return countTable[i]即可,用空间换时间,时间复杂度O(1)
扩展问题:
1.如果变量是32位的DWORD,你会使用哪种算法,或者改进那个算法?
2.另一个相关的问题,给定两个正整数(二进制形式表示)A和B,问把A变为B需要改变多少位?或说整数A与B二进制表示中有多少位是不同的?
解法: 1.查表法不合理,2^32 = 4G,此时解法三不超过32次循环就可以得到结果,比较合适,解法二和解法一需要32次循环得到结果。
2.将A与B异或,然后求异或的结果中1的个数即可。