在剑指offer中有这么一道题:输出一个数的二进制表示中有多少个1??
这道题上手最基本的思想就是:判断最右边的数是不是1,每判断一位,右移一位。这种思想只是判断1与最后一位相与的结果。
代码:
int NumOf1_1(int x)
{
int count = 0;
while (x)
{
if (x & 1)
{
count++;
}
x = x >> 1;
}
return count;
}
但是基于这种解决方法有很大的缺陷,如果是有符号的数呢? 负数?? 因为如果是负数,当你移位后,还要保证移位后还是一个负数,所以会进入死循环。
为了解决这种缺陷,我们可以反过来想,每次不移动输入的整数,而是移动进行判断的“1”。先判断最后一位是不是1,然后把1左移一位得到2,此时判断第二位...
代码:
int NumOf1_2(int x)
{
int count = 0;
size_t flag = 1;
while (flag)
{
if (x & flag)
{
count++;
}
flag = flag<< 1;
}
return count;
}
一种更有意思的解法,将整数减1,再和原来的整数“与”,此时会把整数中从右边开始的第一个1变为0,循环检测整数中二进制表示中有几个1。。。。
代码:
int NumOf1_3(int x)
{
int count = 0;
while (x)
{
++count;
x = (x - 1) &x;
}
return count;
}