【问题描述】
一个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
通过位运算得到十进制数对应二进制数中1的个数
#include <iostream>
#include <string>
using namespace std;
int countOnes(int num) {
int count = 0;
while (num) {//num不为0时循环
count += (num & 1);//当num二进制的最后一位为1时与1进行位运算结果为1
num >>= 1;//将num二进制位右移一位
}//此循环可得num对应二进制的1的个数
return count;
}
int main()
{
int T = 0;
cin >> T;
while (T--)
{
string ip;
cin >> ip;
int d1 = ip.find('.');
string ip1(ip, 0, d1);
int IP1 = stoi(ip1);
int d2 = ip.find('.', d1+1);
string ip2(ip, d1 + 1, d2);
int IP2 = stoi(ip2);
int d3 = ip.rfind('.');
string ip3(ip, d2 + 1, d3);
int IP3 = stoi(ip3);
string ip4(ip,d3+1);
int IP4 = stoi(ip4);
cout << countOnes(IP1) + countOnes(IP2) + countOnes(IP3) + countOnes(IP4) << endl;
}
return 0;
}