继京东618店庆时买的《编程之美》这本书,翻了翻,发现里面的题还是挺有意思的,看起来我们觉得很简单的题目,解法却有很多很多种,真是一个比一个巧妙,于是,决定记录一下。
书中的题目如下
- 对于一个字节(8bit)的无符号数,求其二进制表示中“1”的个数,要求算法的执行效率尽可能高。
就像书中给我们说的一样,我们一般人可能想到的解决方法如下
int countOne(int n){
int count=0;
while(n){
if(n%2==1){
count++;
}
n/=2;
}
return count;
}
然后,有的人可能说我采用移位的方式来解决,但这种方法与上面的方法随大同小异,但在效率上有很大的提升,这是因为移位操作较除、余操作要快。
文章中提到的第三种方法如下:这种方法实在是很巧妙,想不到
int countThree(int n){
int count=0;
while(n){
n&=(n-1);//与一次就可以消掉n中最右边的“1”,因此也就可以统计出来
count++;
}
}
文章中提到的第四种方法:查表法(以空间换取时间),通过空间来换取时间是一个比较常用的方法。
由于8bit的表太长,这里选取的是4bit的表的例子如下
int count_bit4(int n)
{
int countTable[16] =
{
0, 1, 1, 2,
1, 2, 2, 3,
1, 2, 2, 3,
2, 3, 3, 4
} ;
int count =0 ;
while (n)
{
/*即将无符号数n以4位为一组进行“1”的查表统计
*/
count += countTable[n &0xf] ;
n >>=4 ;
}
return count ;
}
根据上面的程序,无论我们的变量n时32为的,还是16为都可以快速的统计出n的二进制数中“1”的个数,这也就解决了《编程之美》2.1节后面的第一个问题。第一个问题如下:
- 如果变量时32为的DWORD,你会使用上述的哪一种算法,或者改进哪一种算法?
第二题
- 判断整数A和B的二进制表示中有多少位是不同的?
也比较简单:先进行异或,然后再判断异或所得结果中“1”的个数
原文:http://blog.csdn.net/u010412719/article/details/46585695