计算int 型数值在内存中二进制1的个数

今天在华为OJ上遇到这么一个题目,很简单,但是却总是得不到最好的成绩记录。因此比较了自己的程序、思路与别人的异同,发现还是有很大区别的,遂记录如下

题目——

输入一个int型整数,求该整数的二进制在内存中有多少个1。例如输入10,由于其二进制表示为1010,有两个1,因此输出2。

思路1

<span style="font-size:18px;">public static void main(String[] args)      {  
    	 
    
         Scanner scanner = new Scanner(System.in);
        int m = scanner.nextInt(); 
        int num = 0;
        while(m>0){
        	m&=(m-1);
        	num++;
        }
        
   
     }  </span><span style="font-size: 16pt;"> 
</span>

这是最常规的思路。直接利用移位去算,始终判断最后一位是不是1,然后计数。这也是我一开始所所想到的,但是,这种写法只得到了60分。



思路2

<span style="font-size:18px;">private static int count_ones(int a)     {
    	    a = (a & 0x55555555) + ((a >> 1) & 0x55555555);
    	    a = (a & 0x33333333) + ((a >> 2) & 0x33333333);
    	    a = (a & 0x0f0f0f0f) + ((a >> 4) & 0x0f0f0f0f);
    	    a = (a & 0x00ff00ff) + ((a >> 8) & 0x00ff00ff);
    	    a = (a & 0x0000ffff) + ((a >> 16) & 0x0000ffff);

    	    return a;
    	}</span><span style="font-size: 16pt;">
</span>


这是我看别人拿了满分的答案。这种思路比较难想到。一开始我怎么都想不明白他是怎么想出来的。直到翻看书籍,碰巧在《编程之美》上有记载这个题目,并且给出了五种解法。其中有两种就是以上两种。

这道题的本质相当于求二进制数的 Hamming 权重,或者说是该二进制数与 0 的 Hamming 距离,这两个概念在信息论和编码理论中是相当有名的。在二进制的情况下,它们也经常被叫做 population count 或者 popcount 问题,比如 gcc 中就提供了一个内建函数:int __builtin_popcount (unsigned int x)   输出整型数二进制中 1 的个数。但是 GCC 的 __builtin_popcount 的实现主要是基于查表法做的,跟编程之美中解法 5 是一样的。Wikipedia 上的解法是基于分治法来做的,构造非常巧妙,通过有限次简单地算术运算就能求得结果,特别适合那些受存储空间限制的算法中使用。

此外,在这个博客里也有对编程之美里五种解法的详细分析,值得一读。http://blog.csdn.net/shijiemazhenda/article/details/6785674  









  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值