剑指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 };