P78、面试题10:二进制中1的个数

题目:请实现一个函数,输入一个整数,输出该数二进制表示中1的个数。例如把9表示成二进制1001,有2位是1。因此如果输入9,该函数输出2.

相关题目:
1)用一条语句判断一个整数是不是2的整数次方。一个整数如果是2的整数次方,那么它的二进制表示中有且只有一位是1,而其他所有位都是0,,根据前面的分析,把这个整数减去1之后再和它自己做与运算,这个整数中唯一的1就会变成0.
2)输入两个整数m和n,计算需要改变m的二进制表示中的多少位才能得到n。比如10的二进制表示为1010,13的二进制表示为1101,需要改变1010中的3位才能得到1101。我们可以分为两位解决这个问题:第一步求这两个数的异或,第二步统计异或结果中1的位数。
 
思路一:
不建议右移输入的数字n,而是把n和1做与运算,判断n的最低位是不是为1。接着把1左移一位得到2,再和n做与运算,就能判断n的次低位是不是1.......这样反复左移,每次都能判断n的其中一位是不是1.
思路二:
把一个整数减去1,都是把最右边的1变成0,。如果它的右边还有0的话,所有的0都变成1,而它左边所有位都保持不变。接下来我们把一个整数和它减去1的结果做位运算,相当于把它最右边的1变成0.还是以前面的1100为例,它减去1的结果是1011.我们再把1100和1011做位与运算,得到的结果是1000。我们把1100最右边的1变成了0,结果刚好就是1000。
总的来说就是:把一个整数减去1,再和原整数做与运算,会把该整数最右边一个1变成0.那么一个整数的二进制表示中有多少个1,就可以进行多少次这样的操作。
 
测试用例:
1)整数(包括边界值1、0x7FFFFFFF)
2)负数(包括边界值0x80000000、0xFFFFFFFF)
3)0
 
代码实现:
package com.yyq;

/**
 * Created by Administrator on 2015/9/11.
 */
public class NumberOfInBinary {
    public static int NumberOf_1(int n){
        int count = 0;
        int flag = 1;
        while(flag != 0){
            if((n & flag )!= 0)
                count++;
            flag = flag << 1;
        }
        return count;
    }

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

    //=========测试用例============
    public static void Test(int number, int expected)
    {
        int actual = NumberOf_1(number);
        if(actual == expected)
           System.out.println("Solution1: Test for " + number + " passed!");
        else
            System.out.println("Solution1: Test for " + number + " fail!");

        actual = NumberOf_2(number);
        if(actual == expected)
            System.out.println("Solution2: Test for " + number + " passed!");
        else
            System.out.println("Solution2: Test for " + number + " fail!");

        System.out.println();
    }

    public static void main(String[] args){
        // 输入0,期待的输出是0
        Test(0, 0);

        // 输入1,期待的输出是1
        Test(1, 1);

        // 输入10,期待的输出是2
        Test(10, 2);

        // 输入0x7FFFFFFF,期待的输出是31
        Test(0x7FFFFFFF, 31);

        // 输入0xFFFFFFFF(负数),期待的输出是32
        Test(0xFFFFFFFF, 32);

        // 输入0x80000000(负数),期待的输出是1
        Test(0x80000000, 1);

    }
}
 
输出结果:
Solution1: Test for 0 passed!
Solution2: Test for 0 passed!
 
Solution1: Test for 1 passed!
Solution2: Test for 1 passed!
 
Solution1: Test for 10 passed!
Solution2: Test for 10 passed!
 
Solution1: Test for 2147483647 passed!
Solution2: Test for 2147483647 passed!
 
Solution1: Test for -1 passed!
Solution2: Test for -1 passed!
 
Solution1: Test for -2147483648 passed!
Solution2: Test for -2147483648 passed!
 
 
 
原文地址:https://www.cnblogs.com/yangyquin/p/4918309.html