统计整数二进制表示中1的个数

统计整数二进制表示中1的个数

ID:15191408

大小:28.00 KB

页数:3页

时间:2018-08-01

统计整数二进制表示中1的个数_第1页
统计整数二进制表示中1的个数_第2页
统计整数二进制表示中1的个数_第3页
资源描述:

《统计整数二进制表示中1的个数》由会员上传分享,免费在线阅读,更多相关内容在行业资料-天天文库

1、2011-10-2123:44C语言统计整数二进制表示中1的个数这是一个很有意思的问题,也是在面试中最容易被问到的问题之一。这个问题有个正式的名字叫Hamming_weight,而且wikipedia上也提供了很好的位运算解决的方法,这个下面也会提到。解决这个问题的第一想法是一位一位的观察,判断是否为1,是则计数器加一,否则跳到下一位,于是很容易有这样的程序。int test(int n){   int count=0;   while(n!=0){     if(n%2==1)count++;     n/=2;   }   return count;}或者和其等价的位运算版本:int 

2、test(int n){   int count=0;   while(n!=0){     count+=n&1;     n>>=1;   }   return count;}这样的方法复杂度为二进制的位数,即,于是可是想一下,有没有只与二进制中1的位数相关的算法呢。可以考虑每次找到从最低位开始遇到的第一个1,计数,再把它清零,清零的位运算操作是与一个零,但是在有1的这一位与零的操作要同时不影响未统计过的位数和已经统计过的位数,于是可以有这样一个操作n&(n-1),这个操作对比当前操作位高的位没有影响,对低位则完全清零。拿6(110)来做例子,第一次110&101=100,这次操作成功

3、的把从低位起第一个1消掉了,同时计数器加1,第二次100&011=000,同理又统计了高位的一个1,此时n已变为0,不需要再继续了,于是110中有2个1。代码如下:int test(int n){   int count=0;   while(n!=0){     n&=n-1;     count++;   }   return count;}这几个方法虽然也用到了位运算,但是并没有体现其神奇之处,下面这个版本则彰显位运算的强大能力,若不告诉这个函数的功能,一般一眼看上去是想不到这是做什么的,这也是wikipedia上给出的计算hamming_weight方法。int test(int 

4、n){   n=(n&0x55555555)+((n>>1)&0x55555555);   n=(n&0x33333333)+((n>>2)&0x33333333);   n=(n&0x0f0f0f0f)+((n>>4)&0x0f0f0f0f);   n=(n&0x00ff00ff)+((n>>8)&0x00ff00ff);   n=(n&0x0000ffff)+((n>>16)&0x0000ffff);    return n;}没有循环,5个位运算语句,一次搞定。比如这个例子,143的二进制表示是10001111,这里只有8位,高位的0怎么进行与的位运算也是0,所以只考虑低位的运算,按

5、照这个算法走一次+---+---+---+---+---+---+---+---+

6、1

7、0

8、0

9、0

10、1

11、1

12、1

13、1

14、  <---143+---+---+---+---+---+---+---+---+

15、 01 

16、  00 

17、 10  

18、  10  

19、  <---第一次运算后+-------+-------+-------+-------+

20、    0001  

21、    0100    

22、  <---第二次运算后+---------------+---------------+

23、        00000101        

24、  <---第三次运算后,得数为5+--------------

25、-----------------+这里运用了分治的思想,先计算每对相邻的2位中有几个1,再计算每相邻的4位中有几个1,下来8位,16位,32位,因为2^5=32,所以对于32位的机器,5条位运算语句就够了。像这里第二行第一个格子中,01就表示前两位有1个1,00表示下来的两位中没有1,其实同理。再下来01+00=0001表示前四位中有1个1,同样的10+10=0100表示低四位中有4个1,最后一步0001+0100=00000101表示整个8位中有5个1。

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。