剑指offer——16二进制中1的个数

 

题目描述

输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
  
有可能引起死循环解法:
  每次判断最右端是不是1【与 & 1即可】,是就cnt++,然后右移一位,直到num为0,结束;
  但是这只对正数有用,而负数右移是左端补充1,这样导致num最终成为 0xFFFFFFFF,从而右移成了死循环。
  
 1 class Solution01 {
 2 public:
 3     int  NumberOf1(int n) {
 4         int cnt = 0;
 5         while (n)
 6         {
 7             if (n & 1)cnt++;
 8             n = n >> 1;
 9         }
10         return cnt;
11     }
12 };

 

常规做法:
  这次,不移num,直接将1左移,然后每移动一次就与 & num,>0,则此位为1;
  
 1 class Solution02 {
 2 public:
 3     int  NumberOf1(int n) {
 4         int cnt = 0;
 5         unsigned num = 1;//一定是无符号的!!!
 6         while (num)
 7         {
 8             if (n & num)cnt++;
 9             num = num << 1;//num<<1不能改变num的
10         }
11         return cnt;
12     }
13 };

 

新颖的做法:
  把一个整数减去1,再和原整数做与运算第会把该整数最右边的1变成0.
  那么一个整数的二进制表示中有多少个1,就可以进行多少次这样的操作。
  
 1 class Solution03 {
 2 public:
 3     int  NumberOf1(int n) {
 4         int cnt = 0;
 5         while (n)
 6         {
 7             ++cnt;
 8             n = (n - 1)&n;
 9         }
10         return cnt;
11     }
12 };

 

  
 
posted @ 2019-10-11 20:19  自由之翼Az  阅读(210)  评论(0编辑  收藏  举报