zoukankan      html  css  js  c++  java
  • 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!
     
     
     
  • 相关阅读:
    css的一些记录——“Unexpected missing generic font family”
    idea右键java文件找到对应的class文件路径以及查看class文件
    redis的一些记录
    【转】解决IDEA2020控制台乱码的方法
    【转】java去除html代码中含有的html、js、css标签,获取文字内容
    linux 中 AGE的含义
    控制反转容器比较:TinyIoC vs Autofac
    C# 异步方法,尽量避免使用async void而是要用async Task
    xamarin 实现选择文件功能
    xamarin手写签名
  • 原文地址:https://www.cnblogs.com/yangyquin/p/4918309.html
Copyright © 2011-2022 走看看