面试题10:二进制中1的个数
题目:请实现一个函数,输入一个整数,输出该数二进制表示中1的个数。例如把9表示成二进制是1001,有2位是1.因此如果输入9,该函数输出2.
1、最简单的做法
//得到二进制1的个数
int NumberOf1(int n)
{
int count = 0;
while(n)
{
if(n%2 != 0)
count++;
n /= 2;
}
return count;
}
因为除法的效率比移位运算要低得多,所以在编程中应该尽可能的用移位运算符代替除法
2、用移位运算
/*每次移动一位,直至整个数字变为0
这种解法循环的次数等于整数二进制的位数,32位的整数需要循环32次。
*/
int NumberOf2(int n)
{
int count = 0;
while(n)
{
if(n & 1)
count++;
n >>= 1;
}
return count;
}
这样写可能会导致死循环。假设输入一个负数,负数每次右移移位左边补1。如果一直做右移运算,最终这个数字就会变成0XFFFFFFFF而陷入死循环。
3、为了避免死循环,最简单的做法
//解决了负数时出现死循环的问题。
int NumberOf3(int n)
{
int count = 0;
unsigned int flag = 1;
while(flag)
{
if(n & flag)
count++;
flag <<= 1;
}
return count;
}
4、避免死循环的同时又高效的做法
//整数有几个1就循环几次
/*eg:n = 1100
n = 1100 & (1100-1) = 1000
n = 1000 & (1000-1) = 0000
*/
int NumberOf4(int n)
{
int count = 0;
while(n)
{
++count;
n = n&n-1;
}
return count;
}