题解 |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 << " ";
    }
}

全部评论

相关推荐

贪食滴🐶:你说熟悉扣篮的底层原理,有过隔扣职业球员的实战经验吗
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务