方法1:采用10进制拆分位数的方法
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
//写一个函数返回参数二进制(补码)中 1 的个数
//分析:
//对于123 -- 想得到每位数 --- 123%10 == 3,123/10 == 12 ---商不等于0,继续
// 12%10 == 2, 12/10 == 1 ---商不等于0,继续
// 1%10 == 1,1/10 == 0 ---商等于0
//对于15 --想得到二进制中的每一位
//00000000 00000000 00000000 00001111
//15%2 == 1 ,15/2 == 7 ---商不等于0,继续
//7%2 == 1, 7/2 == 3 --- 商不等于0 ,继续
//3%2 == 1, 3/2 == 1 --- 商不等于0,继续
//1%2 == 1, 1/2 == 0 --- 商等于0
int NumberOf1(unsigned int n)//注意一定时unsigned int 否则,负数就不准确
{
int count = 0;
while (n)
{
if (n % 2 == 1)
{
count++;
}
n /= 2;
}
return count;
}
int main()
{
int num = 0;
printf("请输入一个数:");
scanf("%d", &num);
int ret = NumberOf1(num);
printf("%d\n", ret);
return 0;
}
方法2:右移操作符
//分析:13
// 00000000 0000000 0000000 00001101
// 00000000 0000000 0000000 00000001 ---与1& 若为1,则该位为1 --- count++
// 其他位时,右移n
// 第二位 :右移1
// 第三位: 右移2
// ...
// 循环:0-31
// 注意:该方法效率低
int NumberOf1(int n)
{
int count = 0;
int i = 0;
for (i = 0; i < 32; i++)
{
if ((n >> i) & 1 == 1)
{
count++;
}
}
return count;
}
int main()
{
int num = 0;
printf("请输入一个数:");
scanf("%d", &num);
int ret = NumberOf1(num);
printf("%d\n", ret);
return 0;
}
方法3:最优方案 -&操作 二进制的理解
//分析: 13 -- 1101 --n ---去掉这个n第一个1
// 12 -- 1100 --n-1
// 1100 --n&(n-1) 去掉n最右边第一个1
// n&(n-1) -- 1100 --n ----去掉这个n第一个1
// 11 -- 1011 --n-1
// 1000 --n&(n-1) 去掉n靠右边第二个1
// n&(n-1) -- 1000 --n ---去掉这个n第一个1
// 10 -- 0111 --n-1
// 0000 --n&(n-1) 去掉n靠右边第三个1
// 为0退出
//计算几次,count几次,1的个数为几次
int NumberOf1(int n)
{
int count = 0;
while (n)
{
n = n&(n - 1);
count++;
}
return count;
}
int main()
{
int num = 0;
printf("请输入一个数:");
scanf("%d", &num);
int ret = NumberOf1(num);
printf("%d\n", ret);
return 0;
}