文章目录
求一个数的二进制表示形式中有多少个1
举个例子:
12转化为二进制是1100,1100中有2个1
对于任意一个数(要在INT_MIN和INT_MAX之间),求它的二进制表示形式中有多少个1,有下面几种方法
1.模2然后在除2
例如a=12
a=12-------- ①a%2=0-------- a/2=6-------- a=6(将a/2的结果在赋给a)
a=6 --------- ②a%2=0-------- a/2=3-------- a=3
a=3---------- ③a%2=1-------- a/2=1-------- a=1
a=1-----------④a%2=1---------a/2=0---------a=0
对a%2从④~①进行排序,得到的就是1100,是12的二进制序列
产生这种情况的原因可以类比于一个十进制数模10除10
例如,对于十进制数123
123%10=3--------123/10=12
12%10=2----------12/10=1
1%10=1-----------1/10=0
可以得到1,2,3
于是,可以利用这个原理去求一个数的二进制表示形式中1的个数
代码如下
#include<stdio.h>
#pragma warning(disable:4996)
int Tobinary(int n)
{
int count = 0;//创建一个计数器
while (n)//n=0,跳出循环
{
if (1 == n % 2)
{
count++;
}
n /= 2;
}
return count;
}
int main()
{
int a = 0;
printf("输入想要进行操作的数\n");
scanf("%d",&a);
int ret=Tobinary(a);
printf("%d\n",ret);
return 0;
}
但是这种方法不能操作负数,下面介绍可以操作负数的方法
2.a&1
例如
a=7
二进制为111
int a=-1,a在内存中的存储就是
11111111 11111111 11111111 11111111(补码)
a&1
11111111 11111111 11111111 11111111
00000000 00000000 00000000 00000001
00000000 00000000 00000000 00000001
a&1=0,则a最后一位一定是0,a&1=1,则a最后一位一定是1。然后将a右移一位(逻辑右移),再次按位与1
*这种方法仅适用于逻辑右移的机器
因为逻辑右移是补0,而算数右移是补原符号位
代码如下
#include<stdio.h>
#pragma warning(disable:4996)
int Tobinary(int n)
{
int count = 0;//创建一个计数器
while (n)//n=0,跳出循环
{
if (n&1)
{
count++;
}
n >>= 1;
}
return count;
}
int main()
{
int a = -1;
int ret=Tobinary(a);
printf("%d\n",ret);
return 0;
}
3.a&(a-1)
这个方法适用于正数和负数,并且不用考虑算数右移和逻辑右移的问题
例如
a=11
a:1011
a-1:1010
a&(a-1)=1010
将a&(a-1)的值在赋给a
a:1010
a-1:1001
a&(a-1)=1000
以此类推,每一次a&(a-1),得到的二进制数中1的个数总是比原来的a少一个
可以利用这个原理求1的个数
#include<stdio.h>
#pragma warning(disable:4996)
int Tobinary(int n)
{
int count = 0;
while (n)//n=0,跳出循环
{
n &= n - 1;
count++;
}
return count;
}
int main()
{
int a = 2396;
int ret=Tobinary(a);
printf("%d\n",ret);
return 0;
}
4.递归
递归方法不需要计数器
对于正数,左移一位不改变二进制表示形式中1的个数
对于负数,左移一位二进制表示形式中1的个数减少一位
#include<stdio.h>
#pragma warning(disable:4996)
int Tobinary(int n)
{
if (n>0)
{
return Tobinary(n<<1);
}
else if (n<0)
{
return Tobinary(n << 1) + 1;
}
else
{
return 0;
}
}
int main()
{
int a = 2396;
int ret=Tobinary(a);
printf("%d\n",ret);
return 0;
}