在讲方法前,我们先了解一下前置知识
我们要知道1个整型在内存中的二进制是32个bit位
然后会采用&这个位运算符,即对应二进制位,有0则为0,同时为1才为1
方法一:
根据我们的前置知识,
00000000000000000000000000000101 —— 5 的二进制
00000000000000000000000000000001 —— 1 的二进制
00000000000000000000000000000001 —— 5 &1 的二进制
00000000000000000000000000000010 —— 5 >> 1 ( 5 右移一个bit位)
00000000000000000000000000000001 —— 1 的二进制
00000000000000000000000000000000 —— 5 &1 的二进制
以此类推
int found_1(int n)
{
int i = 0;
int count = 0;
for (i = 0; i < 32; i++)// 因为 i 是从 0 开始的,第一次 n >> i 相当于没有移
{
if (((n >> i) & 1) == 1)
{
count++;
}
}
return count;
}
int main()
{
int n = 0;
scanf("%d", &n);
int ret = found_1(n);
printf("%d", ret);
return 0;
}
方法二:
假如是一个十进制数,我们想要得到每一位,我们可以%10/10
1234 % 10 = 4
1234 / 10 = 123
123 % 10 = 3
123 / 10 = 12
二进制则同理捏
假如 10 这个数,它的二进制数是 00000000000000000000000000001010
10 % 2 = 0 —— 相当于把 10 的二进制的最低位也就是最右边的 0 拿到了
10 / 2 = 5 —— 5 的二进制是 00000000000000000000000000000101 相当于去掉了 10 的二进制最低位也就是最右边 0
5 % 2 = 1 —— 相当于把 5 的二进制的最低位也就是最右边的 1 拿到了
5 / 2 = 2 —— 2 的二进制是 00000000000000000000000000000010 相当于去掉了 5 的二进制最低位也就是最右边 1
2 % 2 = 0 —— 相当于把 2 的二进制的最低位也就是最右边的 0 拿到了
2 / 2 = 1 —— 1 的二进制是 00000000000000000000000000000001 相当于去掉了 2 的二进制最低位也就是最右边 0
所以我们直接上代码
int found_1(int n)
{
int count = 0;
while (n)
{
if (n % 2 == 1)
count++;
n = n / 2;
}
return count;
}
int main()
{
int n = 0;
scanf("%d", &n);
int ret = found_1(n);
printf("%d", ret);
return 0;
}
方法三:
这个方法比较巧妙,
n = n & ( n-1 ) ,假如输入 n = 13 ,13 的二进制 1101
1101 —— n
1100 —— n-1
1100 —— n & n-1 再赋给 n、
1011 —— n-1
1000 —— n & n-1 再赋给 n
0111 —— n-1
0000 —— n & n-1 再赋给 n
执行几次就有几个1,直至n=0为止
int found_1(int n)
{
int count = 0;
while (n)
{
n = n & (n - 1);
count++;
}
return count;
}
int main()
{
int n = 0;
scanf("%d", &n);
int ret = found_1(n);
printf("%d", ret);
return 0;
}
本文介绍三种高效算法来计算一个整数中二进制表示的1的个数,包括位运算、模除操作及巧妙的迭代减1与按位与运算。

被折叠的 条评论
为什么被折叠?



