【剑指offer】15、二进制中1的个数

题目

请实现一个函数,输入整数,输出二进制表示中1的个数。

思路1

复习左移操作和右移操作:

左移:右边补0

右移:如果是无符号数,直接补0;如果是符号数,用符号补。

不断与1做 与运算,然后计数,然后将数字右移一位。注意将数字除以2也一样,但是右移操作更加有效率。

但是当输入数字是负数时,最左位是1,不断与1做”与“运算会陷入死循环。

class Solution {
public:
    int  NumberOf1(int n) {
        //  当输入负数时,会引起死循环
         int count = 0;
         while( n != 0){
             if ( n & 1){
                 count++;
                 n = n >> 1;
             }
         }
         return count;
    }
};

思路2

让n不断与1、10、100、1000做与运算。

缺点:如果是32位的整数,就需要循环32次。

class Solution {
public:
    int  NumberOf1(int n) {
        int count = 0;
        unsigned int flag = 1;
        while (flag){
            if (n & flag){
                count++;
            }
            flag = flag << 1;
        }
        return count;
    }

思路3

把该数字和自己减去1后,做与运算。效果相当于把最右边的1变成0。

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

拓展

1、用一条语句判断一个整数是不是2的整数次方:

扫描二维码关注公众号,回复: 2057213 查看本文章

因为2的整数次方只有一个1,因此只需要判断  n & (n-1)之后是否为0;

2、输入两个整数m与n,计算需要改变m的二进制中多少位才能得到n:

将两个数字做异或,然后用思路3的做法统计1的个数,这就是他们不同的位数。

猜你喜欢

转载自www.cnblogs.com/shiganquan/p/9291190.html