zoukankan      html  css  js  c++  java
  • 二进制中1的个数

    题目

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

    可能引起死循环的解法

    一个基本的思路:先判断整数二进制表示中最右边一位是不是1。接着把输入的整数右移一位,此时原来处于从右边数起的第二位被移到最右边了,再判断是不是1。这样每次移动一位,直到整个整数变成0为止。

            怎么判断一个整数的最右边是不是1:只要把整数和1做位与运算看结果是不是0就知道了

    int NumberOf1Solution1(int n)
        {
            int count = 0;
    
            while (n > 0)
            {
                if ((n & 1) == 1)
                {
                    count++;
                }
    
                n = n >> 1;
            }
    
            return count;
        }

    右移运算符m>>n表示把m右移n位。右移n位的时候,最右边的n位将被丢弃。

    如果数字原先是一个正数,则右移之后在最左边补n个0;如果数字原先是负数,则右移之后在最左边补n个1。例如下面对两个八位二进制数进行右移操作:

    00001010>>2=00000010

    10001010>>3=11110001

    那么,问题来了:上面的方法如果输入一个负数,比如0x80000000,如果一直做右移运算,最终这个数字就会变成0xFFFFFFFF而陷入死循环

    避免引起死循环的解法

    不右移输入的数字i:

    1. 首先把i和1做与运算,判断i的最低位是不是为1。
    2. 接着把1左移一位得到2,再和i做与运算,就能判断i的次低位是不是1。
    3. 这样反复左移,每次都能判断i的其中一位是不是1。
    #include <iostream>
    using namespace std;
    
    class Solution
    {
        public:
            int one_count(int n);
            int num_of_one(int n);
    };
    int Solution::one_count(int n)
    {
        unsigned int flag=1;//最大的表示范围 这个解法中循环的次数等于整数二进制的位数,32位的整数需要循环32次。
        int sum=0;
        while(flag)
        {
            if(n&flag)
                ++sum;
            flag=flag<<1;
        }
        return sum;
    }
    int Solution::num_of_one(int n)
    {
        /*
         *把一个整数减去1,再和原整数做与运算,会把该整数最右边一个1变成0。
         *那么一个整数的二进制表示中有多少个1,就可以进行多少次这样的操作。
         */
        int sum=0;
        if(n==0)
            return 0;
        while(n)
        {
            ++sum;
            n=n&(n-1);//相当于把二进制最右边的1变成0 
        }
        return sum;
    }
    int main()
    {
        int n;
        cin>>n;
        Solution s;
        cout<<s.one_count(n)<<endl;
        cout<<s.num_of_one(n)<<endl;
        return 0;
    }

    拓展

    1. 把一个整数减去1,再和原整数做与运算,会把该整数最右边一个1变成0。那么一个整数的二进制表示中有多少个1,就可以进行多少次这样的操作。
    2. 把一个整数减去1之后再和原来的整数做位与运算,得到的结果相当于是把整数的二进制表示中的最右边一个1变成0。很多二进制的问题都可以用这个思路解决。
    3. 用一条语句判断是不是2的整数次方。如果是2的整数次方,那么2进制中有且只有一位是1,其他位都是0,把这个数的本身与其减一后相与,这个数中的唯一的1就变成0,。
  • 相关阅读:
    EJB>依赖注入(dependency injection) 小强斋
    EJB>自定义安全域 小强斋
    EJB>定时服务(Timer Service) 小强斋
    EJB>依赖注入(dependency injection) 小强斋
    EJB>定时服务(Timer Service) 小强斋
    EJB>安全服务的具体开发 小强斋
    EJB>JMS(Java Message Service)和消息驱动bean 小强斋
    EJB>拦截器(Interceptor) 小强斋
    《做最好的员工》第二章:好员工擅长合作
    教你29招,让你在社交,职场上人人对你刮目相看 !
  • 原文地址:https://www.cnblogs.com/tianzeng/p/10146501.html
Copyright © 2011-2022 走看看