#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
int main()
{
int a = 0;
scanf("%d", &a);
int count = count_bit_one(a);
printf("count = %d\n", count);
return 0;
}
算法一(类比十进制的%10得到最后一位数字,再/10去掉最后一位数字):
int count_bit_one(int a)
{
int count=0;//计数器
while (a)//a=0时跳出循环
{
if (a % 2 == 1)
count++;
a = a / 2;
}
return count;
}
缺点:如果a是负数,则a会跳出循环,比如 - 1/2=0;
优化:把a定义成无符号数,除去二进制中符号位对结果的影响
int count_bit_one(unsigned int a)
{
int count=0;//计数器
while (a)//a=0时跳出循环
{
if (a % 2 == 1)
count++;
a = a / 2;
}
return count;
}
算法二:按位与判断二进制每一位,再用移位操作符
int count_bit_one(int a)
{
int count = 0;
int i = 0;
for (i = 0; i < 32; i++)
{
if (((a >> i) & 1) == 1)//位操作符(用于二进制),按位与
count++;
}
return count;
}
更优:算法三:
我们先来看 n=n&(n-1)这个算法
假如一开始n等于13
二进制
1101 n
1100 n-1(12)
1100 n
1011 n-1(11)
1000 n
0111 n-1(8)
0000 n
结论:我们观察每个n,发现每次经过一轮n&(n-1)运算之后的n,二进制位最低位都可以消除一个1,二进制都减少了一个1。最后到全为0,经过了多少轮,就有多少个1
int count_bit_one(int n)
{
int count = 0;
while (n)
{
n = n & (n - 1);
count++;
}
return count;
}
总结:前两种方法相似,都要将整个32个比特位都比较完,比较浪费时间和空间,而这个算法二进制有多少个1就计算多少次。
编程小白,如有问题,请多指教Thanks♪(・ω・)ノ