题解 |HJ18 #识别有效的IP地址和掩码并进行分类统计#
识别有效的IP地址和掩码并进行分类统计
https://www.nowcoder.com/practice/de538edd6f7e4bc3a5689723a7435682
#include <iostream>
#include <memory>
#include <sstream>
#include <stdexcept>
#include <string>
#include <vector>
using namespace std;
vector<string> split(const string& str, const char pattern) {
vector<string> res;
stringstream input(str);
string temp;
while (getline(input, temp, pattern)) {
res.push_back(temp);
}
return res;
}
string toBin(int num) {
string res;
while (num > 0) {
res.push_back(num % 2 + '0');
num = num / 2;
}
res.resize(8, '0');
// 构造
return {res.rbegin(), res.rend()};
}
bool checkMask(string& mask) {
// 先判断子网掩码是否合法
auto maskNums = split(mask, '.');
if (maskNums.at(0) == "0" || maskNums.at(3) == "255") {
return false;
}
// 标记 '0' 是否出现
bool flag = false;
for (auto maskNum : maskNums) {
// 对掩码的每个数字取二进制
int n = stoi(maskNum);
auto maskBin = toBin(n);
// cout << maskNum << endl;
// cout << maskBin << endl;
// 如果出现了0,则置flag
for (auto b : maskBin) {
if (b == '0')
flag = true;
// 已经出现 0 后又出现1,不合法
if (flag && b == '1') {
return false;
}
}
}
return true;
}
bool checkIp(string& ip, vector<int>& res) {
auto nums = split(ip, '.');
if (nums.size() != 4) {
return false;
}
for (auto num : nums) {
if (num.empty()) {
return false;
}
}
if (nums.at(0) == "127" || nums.at(0) == "0") {
res.at(5)--;
return false;
}
return true;
}
void solve(string& ip, string& mask, vector<int>& res) {
if (res.size() != 7) {
cout << "size error" << endl;
}
// 掩码有误 或 ip 有误
if (!checkIp(ip, res) || !checkMask(mask)) {
res.at(5)++;
return;
}
// ip类型
auto nums = split(ip, '.');
try {
int n1 = stoi(nums.at(0));
int n2 = stoi(nums.at(1));
int n3 = stoi(nums.at(2));
int n4 = stoi(nums.at(3));
if (n1 <= 126 && n1 >= 1) {
// cout << ip << "--" << mask << endl;
res.at(0)++;
}
if (n1 >= 128 && n1 <= 191) {
res.at(1)++;
}
if (n1 >= 192 && n1 <= 223) {
res.at(2)++;
}
if (n1 >= 224 && n1 <= 239) {
res.at(3)++;
}
if (n1 >= 240 && n1 <= 255) {
res.at(4)++;
}
// 私有ip
if (n1 == 10) {
res.at(6)++;
}
if (n1 == 172 && (n2 >= 16 && n2 <= 31)) {
res.at(6)++;
}
if (n1 == 192 && n2 == 168) {
res.at(6)++;
}
return;
} catch (std::invalid_argument) {
return;
}
}
int main() {
vector<int> res(7, 0);
string line;
while (getline(cin, line)) {
auto splits = split(line, '~');
auto ip = splits.at(0);
auto mask = splits.at(1);
solve(ip, mask, res);
}
for (auto r : res) {
cout << r << " ";
}
}
