【题目描述】
请实现一个函数,输入一个整数,输出该数二进制表示中1的个数。例如把9表示成二进制是1001,有两位是1,因此输出2。
【解决方案】
1. 可能引起死循环的解法
判断数n最右一位是否是1,只需把它和1做与运算即可知道(因为1除了最右一位为1,其余位为0),然后右移操作,高位补0,直到n为0。
但是如果n为负数,对其进行右移操作后,其最高位补1,一直右移下去,n的值会全部为1,n永远不为0,造成死循环。
1 public static int GetOneNum(int n) 2 { 3 int count = 0; 4 5 while (n != 0) 6 { 7 if ((n & 1) != 0) 8 { 9 count++; 10 } 11 n = n >> 1; 12 } 13 return count; 14 }
2. 常规解法
右移对于负数造成死循环,那我们可以通过设置flag,让flag从最低位往最高位移动,直到flag为0来对n的每位进行与操作,来统计n的二进制表示方法中1的个数。
但是对于32的整数,需要循环进行32次,下面第三种解决方法只需要循环n中1的个数的次数。
1 public static int GetOneNum(int n) 2 { 3 int count = 0; 4 int flag = 1; 5 6 while (flag != 0) 7 { 8 if ((n & flag) != 0) 9 { 10 count++; 11 } 12 flag = flag << 1; 13 } 14 return count; 15 }
3. 能给面试官带来惊喜的解法
a. n(1100)减一,赋值为temp(1011);
b. n和temp进行与运算,结果赋值给n(1000);
c. 重复a,b步骤,可以依次消除n中的1,并统计1的个数;
1 public static int GetOneNum(int n) 2 { 3 int count = 0; 4 int temp = 0; 5 6 while (n != 0) 7 { 8 temp = n - 1; 9 n &= temp; 10 count++; 11 } 12 return count; 13 }
【相关题目】