【问题描述】
一个IP地址由32位二进制的数组成,比如:
111111111111111111111111000000002
为了便于记忆,我们将8个二进制位用一个十进制数表示,一个IP地址由四个十进制数表示,上述的IP地址表示为:
255.255.255.0
现在给你一个上述形式的IP地址,请回答IP地址的32个二进制位中,有多少位是1。
如IP地址为255.255.255.0,其中24位是1。
【输入形式】
有多组测试数据。
测试数据第一行是一个正整数T,表示测试数据组数。
每组测试数据是一个IP地址,形式为:
IP1.IP2.IP3.IP4
其中0 ≤IP1,IP2,IP3,IP4≤ 255,用十进制表示。每个IP地址不保证是实用IP地址。
40%的测试数据组数T 10≤T≤ 102;
30%的测试数据组数T 102≤T≤ 103;
20%的测试数据组数T 103≤T≤ 104;
10%的测试数据组数T 104≤T≤ 105;
【输出形式】
对于每个IP地址,输出一行包含一个非负整数:该IP地址的32个二进制位中,1的位数。
【样例输入】
5
255.255.255.0
127.0.0.1
0.0.0.1
1.2.3.4
0.0.0.0
【样例输出】
24
8
1
5
0
提示:样例中32位的IP地址为:
111111111111111111111111000000002
011111110000000000000000000000012
000000000000000000000000000000012
000000010000001000000011000001002
000000000000000000000000000000002
此题刚开始以为要求出二进制IP地址,所以开始时求出来了,这里没有展示,写完后发现如果要求IP地址的话,主要难点在于补零补足八位数,以及整型数和字符串间的转换,字符串的拼接(我写的时候用的加和,用find函数找出字符串中含有某个特定字符的个数的统计. 转换二进制IP地址值得我们去写一下。
言归正传,这题的解题思路主要是用结构体进行输入数据,分部分处理IP地址,分别求出四个部分的1的个数(涉及取余,整除),加和即可。我写了一个ff()函数用于求每个部分转换为二进制时1的个数。 下面是代码,有详细注释。有错还望各位指正!
#include
#include
using namespace std;
struct Ip//采用结构体进行输入IP地址,方便后面对它进行处理
{
int num1;
int num2;
int num3;
int num4;
char s;
};
int ff(int n)//计算每个整数转换为二进制后含有的1的个数
{
int k=n;
int t=0;
int count=0;
int g[8],h[8];
for(int i=0;i<8;i++)
{
g[i]=0;
h[i]=0;
}
while(k!=0)
{
g[t]=k%2;//取余
k=k/2;//整除
t++;//统计取余次数
}
for(int i=0;i>m;
Ip bb[m];//m个IP地址
int count[m];//存储m个IP地址的1的个数
for(int i=0;i>bb[i].num1>>bb[i].s>>bb[i].num2>>bb[i].s>>bb[i].num3>>bb[i].s>>bb[i].num4;
//一个IP地址的额1的个数为原始IP地址的四个整数组成部分转化为二进制的1的个数总和
count[i]=ff(bb[i].num1)+ff(bb[i].num2)+ff(bb[i].num3)+ff(bb[i].num4);
}
for(int i=0;i