剑指offer 二进制中1的个数

题目描述

输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
 
代码一:
 1 class Solution {
 2 public:
 3      int  NumberOf1(int n) {
 4          int count = 0;
 5          while (n) {
 6              if (n & 1) {
 7                  count++;
 8              }
 9              n >>= 1;
10              //n = n & (n - 1);
11              
12          }
13          return count;
14      }
15 };

有问题,出现死循环,原因在于如果输入的是负数, 如0x80000000, 右移一位之后会变成0xC0000000, 而不是0x40000000,经过多次移位,最终会变成0xFFFFFFFF

 

代码二:我们不右移数字,而是左移1.这种做法,32位的整数需要左移32次

 1 class Solution {
 2 public:
 3      int  NumberOf1(int n) {
 4          int count = 0;
 5          unsigned int flag = 1;
 6          while (flag) {
 7              if (n & flag) {
 8                  count++;
 9              }
10              flag <<= 1;
11              //n = n & (n - 1);
12              
13          }
14          return count;
15      }
16 };

代码三:每一次 n & (n - 1)操作相当于把n对应二进制最右边的1变成0,循环次数为n中1的个数。

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

 

 

相关题目:

1、输入两个整数m和n, 计算需要改变m的二进制表示中的多少位才能得到n。

思路:第一步:将两个数进行异或操作(^),得到两个数的二进制差别,

第二步:统计异或结果中1的个数。

2、用一条语句判断一个整数是否是2的整数次方。

思路:如果一个数是2的整数次方,那么它的二进制表示中有且只有一位是1, 那么n & (n - 1) = 0。

posted @ 2019-07-25 18:19  琴影  阅读(253)  评论(0编辑  收藏  举报