二进制中1的个数

question:输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。

本题需要知道的一点是:一个整数也就是int类型4个字节,一个字节有8位,所以一共就有32位

resolution1:

该方法的思路是一种比较容易想到的思路。要统计一个32位的二进制数中1的个数,那么就可以依次遍历这32位数,判断为1 还是 0

那么如何遍历呢?这里就要借助Java的toBinaryString()方法将十进制数转为二进制数(当然这种直接调用库函数的方法在面试中就不要用了,毕竟不是出题人的意图,如果是应付笔试的话当然是怎么简单怎么来了)

 public int NumberOf1(int n) {
        String bs = Integer.toBinaryString(n);
        int count = 0;
        for(int i = 0; i< bs.length(); i++){
            if(bs.charAt(i) == '1'){
                count++;
            }
        }
        return count;

    }

resolution2:

  • 该方法也是在方法一的基础上来的,只是这里的遍历借助了移位的思想,依次将32位数向右移动,直到将首位移动到最后一位
  • 其次,这里的每移动一位相与是指将最后一位和二进制的1进行相与,相当于吐弹珠,吐一个对比一个

  • 由于考虑到负数的情况,这里采用的是无符号右移<<<,即向右移多少位,就在前面添加多少个0;这里不采用符号符号右移<<的原因是负数有符号右移时,右移多少位,就在前面添加多少个1。
  • 而此题我们讨论的是统计1的个数,所以如果采用有符号右移,那么右移多少位,前面又会补多少个1,所以就是一个死循环了
 public int NumberOf1(int n) {

        int count = 0;
        for(int i = 0; i < 32; i++){
            if((n >>> i & 1) == 1){
                ++count;}
        }
        return count;
    }

resolution3:

  • 该方法的精妙之处在于利用了这样一个性质:两个相邻的二进制数n、n-1 相与,其结果中1的个数 = n中1的个数 - 1那么就可以依次递归,直到n为0,那么肯定就不包含1了。

  public int NumberOf1(int n) {
        int count = 0;
        while(n!= 0){
            count++;
            n = n & (n - 1);
        }
        return count;

    }

 附上一个例子当n=5时的情况:

****************
101==>n:5
100==>n-1:4
100==>n & n-1:4
count:1
****************
100==>n:4
11==>n-1:3
0==>n & n-1:0
count:2
2

 

欢迎关注我的公众号:小秋的博客 CSDN博客:https://blog.csdn.net/xiaoqiu_cr github:https://github.com/crr121 联系邮箱:rongchen633@gmail.com 有什么问题可以给我留言噢~
原文地址:https://www.cnblogs.com/flyingcr/p/10326839.html