前言:这里介绍三种算法,来解决这个问题
目录
-
算法一
思路:将负数转换为正数,避免补码的计算;让n的值逞递减变化直到为0
int One_Count(int n)
{
int a = 0;
int count = 0;//用来计算1的个数
int i = 0;
if (n < 0)
{
n = -n;
i = 1;
}
while (n != 0)
{
a = n & 1;
if (a == 1)
{
count++;
n = n >> 1;
}
else
{
n = n >> 1;
}
}
if (i == 0)
return count;
else
return count + 1;//这里的1指的是负数原码最高位那个
}
int main()
{
int n = 0;
scanf("%d", &n);
int ch = One_Count(n);
printf("%d\n", ch);
}
-
算法二
思路:对该数进行 %2 和 /2 的操作,将二进制序列的每一位拿下来
int One_Count(unsigned int n)//此算法因为要应对负数所以对参数类型有要求
// 需是unsigned int类型
{
int count = 0;
while (n)
{
if (n % 2 == 1)
count++;
n = n / 2;
}
return count;
}
int main()
{
int n = 0;
scanf("%d", &n);
int ch = One_Count(n);
printf("%d\n", ch);
}
如:输入-1,结果显示为:32
我们拿整数15和-1的例子进一步补充:
- 算法思路图解
- unsigned int 类型参数图解
-
算法三
声明:该算法是算法一的升级版,这里n的值没有发生变化,也避免了当n可变且为负数时,按位右移时左侧补1进入死循环的问题
思路:通过循环将这32位一个一个拿出
特点:代码简洁,效率高
int One_Count(int n)
{
int i = 0;
int count = 0;
for (i = 0; i < 32; i++)
{
if (((n >> i) & 1) == 1)//这里注意下关系运算符的优先级高于位运算符
{
count++;
}
}
return count;
}
int main()
{
int n = 0;
scanf("%d", &n);
int ch = One_Count(n);
printf("%d\n", ch);
}
总结:三种算法各有各的特点,希望可以帮助到大家