题目
请实现一个函数,输入一个整数,输出该数二进制表示中1的个数。例如,把9表示成二进制是1001,有俩位是1.因此,如果输入9,则函数输出2。
类似题目在leetcoed上191. 位1的个数也有。
分析
求余法
我们让num每次%2求余,得到是1就让count++;然后让num/2。直到num为0为止。
缺陷就是不能判断负数。
C
#include<stdio.h> int NumberOf(int n) { int count = 0; while (n > 0) { if (n % 2 == 1) { count++; } n = n / 2; } return count; } int main() { int count = NumberOf(9); printf("二进制中1的个数:%d\n", count); return 0; }
位运算
如果了解位运算,我们还可以优化代码。&与运算。只有俩边都为1才为1。
位运算快于除法,还是没能解决负数
C
#include<stdio.h> int NumberOf(int n) { int count = 0; while (n > 0) { count = n & 1; n = n >> 1; } return count; } int main() { int count = NumberOf(9); printf("二进制中1的个数:%d\n", count); return 0; }
二进制串法
因为给的是int类型,四个字节,每一个字节8位,共4*8=32位。这样就可以一位一位的判断。成功解决了负数的问题
C
#include<stdio.h> int NumberOf(int n) { int count = 0; int i = 0; for (i = 0; i < 32; i++) { if ((n & (1 << i)) != 0) { count++; } } return count; } int main() { int count = NumberOf(9); printf("二进制中1的个数:%d\n", count); return 0; }
优化位运算
我们其实可以让num与num-1做与运算。发现也可以,每次消去num的一个1。
C
#include<stdio.h> int NumberOf(int n) { int count = 0; while (0 != n) { count++; n &= (n - 1); } return count; } int main() { int count = NumberOf(9); printf("二进制中1的个数:%d\n", count); return 0; }
本章完!