题目一:首先编写代码实现:求一个整数存储在内存中的二进制中1的个数。
法一:
当我们看见这个题,第一个想到的应该就是如下的代码:
#include <stdio.h>
int main()
{
int num = 10;
int count = 0;//计数
while (num)
{
if (num % 2 == 1)
count++;
num = num / 2;
}
printf("二进制中1的个数 = %d\n", count);
return 0;
}
这个代码的确能轻松的算出一个数转化为二级制后并能快速的求出其中1的个数,但是有缺陷,比如,如果要计算的是一个负数,他就不能实现。
法二:
那么加以修改,因为我们要算的是一个数转化为二进制中1的个数,这里我们用到了两个位运算符,与运算符“&”和右移运算符“>>”,我们之前已经学过,与运算符“&”的特性:当两个数进行与运算,都为1才为1,有一个为0,就为0。那么我们可以将所要计算的数与1进行与运算,如果得到的值为1,说明当前二进制位的最后一位为1。接下来就让这个数的二进制位进行右移运算,然后反复操作,直到32位二进制位都计算过后为止。
代码如下:
#include <stdio.h>
int main()
{
int num = -1;
int i = 0;
int count = 0;//计数
for(i=0; i<32; i++)
{
if( ((num>>i)&1) == 1 )
count++;
}
printf("二进制中1的个数 = %d\n",count);
return 0;
}
这段代码不仅解决了第一次不能计算负数的缺陷,又更加的清晰的解释了如何计算1的个数。
法三:
第三种方法就比较难想象到了,此法巧妙的运用了与运算符“&”
代码如下:
#include <stdio.h>
int main()
{
int num = -1;
int i = 0;
int count = 0;//计数
while(num)
{
count++;
num = num&(num-1);
}
printf("二进制中1的个数 = %d\n",count);
return 0;
}
题目二:
小武同学的算术题
描述
小武同学最近在做老师发的作业题,在给定的n个数中,求出每个数转为二进制后包含1的个数,可是题目数太多了,于是小武同学想请你帮忙来解决,你能帮帮她吗?
样例解释
1,2,3的二进制为01 10 11.
样例说明
1<=n<=500
输入
第一行输入一个数整数n,第二行输入一个n个整数。
输出
输出每个数中1的个数,以空格分隔。
当我们掌握了上边的算法后,这个题目当然迎刃而解:
直接上代码:
#include<stdio.h>
int main()
{
int n = 0;
scanf("%d", &n);
for (int j = 0; j < n; j++)
{
int count = 0;
int num = 0;
scanf("%d", &num);
while (num)
{
num = num & (num - 1);
count++;
}
printf("%d ", count);
}
return 0;
}
题目三:
数位之和
描述
给定2个十进制整数n和m,请输出n到m之间所有奇数的数位之和的总和。
125的数位之和是1+2+5=8。
样例说明
1+3+5+7+9=25
输入
输入格式
输入2个整数n和m。
输出
输出一个整数表示答案
首先我们要知道怎么获取一个数的每一位,这里我们用到了我们的取模%,当将一个数取模10就可以得到他的个位。这个题目比较简单,直接上代码:
#include<stdio.h>
int main()
{
int n, m;
scanf("%d%d", &n, &m);
int sum = 0;
for (int i = n; i <= m; i++)
{
int j = i;
if (j % 2!= 0)
{
while (j)
{
int temp = 0;
temp = j % 10;
sum += temp;
j /= 10;
}
}
}
printf("%d", sum);
return 0;
}
这里需要注意的是,在使用i的值的时候必须用一个变量来接受它,因为我们在使用的过程中会牵扯到改变i的值,如果不用一个变量来接受,会造成循环出错。
好的,今天的分享就到这里,谢谢大家。