问题:
请实现一个函数,输入一个整数,输出该数二进制表示中1的个数。例如把9表示成二进制是1001,有2位是1,因此如果输入9,该函数输出2。
方法一:
int countOf1(int num) {
int ret = 0;
int i = 0;
for (i = 0; i < 32; i++) {
ret += ((num & 0x80000000) ? 1 : 0);
num <<= 1;
}
return ret;
}
方法二:
int coutOf1_method2(int num) {
int count = 0;
count = (num == 0) ? 0 : 1;
while ((num & (num - 1)) != 0) {
count++;
num &= num - 1;
}
return count;
}
方法一和方法二无所谓哪个更好,时间复杂度相同,都是O(n)。
需要注意:
方法一中如果输入的数字是负数的话那么右移会引起死循环,而左移不会。这也应该是这道题的陷阱所在。
相关题目:
1. 用一条语句判断一个整数是不是2的整数次方。一个整数如果是2的整数次方,那么它的二进制表示中有且只有一位是1,而其他所有位都是0.根据前面的分析,把这个整数减去1之后再和它自己做与运算,这个整数中唯一的1就会变成0.
2. 输入两个数m和n,计算需要改变m的二进制表示中多少位才能得到n。比如10的二进制表示为1010,13的二进制表示为1101,需要改变1010中的3位才能得到1101。
两种解决方法:
方法一:第一步求异或,第二步统计结果中1的个数。
方法二:循环右移32次,每次比较每一位。