题解 | 识别有效的IP地址和掩码并进行分类统计

识别有效的IP地址和掩码并进行分类统计

https://www.nowcoder.com/practice/de538edd6f7e4bc3a5689723a7435682

#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <cctype>

using namespace std;

// 判断字符串是否为纯数字,且无前导零(允许0)
bool is_valid_segment(const string& s) {
    if (s.empty()) return false;
    if (s.size() > 1 && s[0] == '0') return false;
    for (char ch : s) if (!isdigit(ch)) return false;
    return true;
}

// 将字符串按 '.' 分割
vector<string> split(const string& s, char delim) {
    vector<string> res;
    stringstream ss(s);
    string item;
    while (getline(ss, item, delim)) res.push_back(item);
    return res;
}

// 检查IP是否合法
bool is_valid_ip(const vector<string>& ip) {
    if (ip.size() != 4) return false;
    for (const string& seg : ip) {
        if (!is_valid_segment(seg)) return false;
        int num = stoi(seg);
        if (num < 0 || num > 255) return false;
    }
    return true;
}

// 检查掩码是否合法
bool is_valid_mask(const vector<string>& mask) {
    if (mask.size() != 4) return false;
    string bin;
    for (const string& seg : mask) {
        if (!is_valid_segment(seg)) return false;
        int num = stoi(seg);
        if (num < 0 || num > 255) return false;
        for (int i = 7; i >= 0; --i)
            bin += ((num >> i) & 1) ? '1' : '0';
    }
    // 合法掩码是若干1后若干0,中间不能出现01->0->1
    size_t first_zero = bin.find('0');
    if (first_zero == string::npos) return false; // 全1非法
    size_t first_one_after_zero = bin.find('1', first_zero);
    if (first_one_after_zero != string::npos) return false;
    // 全0非法
    if (bin.find('1') == string::npos) return false;
    return true;
}

// 判断IP类型
int get_ip_type(const vector<string>& ip) {
    int first = stoi(ip[0]);
    if (first >= 1 && first <= 126) return 0; // A
    if (first >= 128 && first <= 191) return 1; // B
    if (first >= 192 && first <= 223) return 2; // C
    if (first >= 224 && first <= 239) return 3; // D
    if (first >= 240 && first <= 255) return 4; // E
    return -1;
}

// 判断是否私有IP
bool is_private_ip(const vector<string>& ip) {
    int a = stoi(ip[0]), b = stoi(ip[1]);
    if (a == 10) return true;
    if (a == 172 && b >= 16 && b <= 31) return true;
    if (a == 192 && b == 168) return true;
    return false;
}

int main() {
    string line;
    int cnt[7] = {0}; // A, B, C, D, E, 错误, 私有
    while (getline(cin, line)) {
        if (line.empty()) continue;
        size_t pos = line.find('~');
        if (pos == string::npos) continue;
        string ip_str = line.substr(0, pos);
        string mask_str = line.substr(pos + 1);
        vector<string> ip = split(ip_str, '.');
        vector<string> mask = split(mask_str, '.');

        // 特殊判断
        if (ip.size() != 4) { cnt[5]++; continue; }
        if (ip[0] == "0" || ip[0] == "127") continue;

        if (!is_valid_ip(ip) || !is_valid_mask(mask)) {
            cnt[5]++;
            continue;
        }

        int t = get_ip_type(ip);
        if (t >= 0 && t <= 4) cnt[t]++;
        if (is_private_ip(ip) && t >= 0 && t <= 2) cnt[6]++;
    }
    for (int i = 0; i < 7; ++i) {
        cout << cnt[i];
        if (i != 6) cout << " ";
    }
    cout << endl;
    return 0;
}

全部评论

相关推荐

mjasjon:这种trash中厂 简历过筛概率比大厂还低(除阿里系)
投递哔哩哔哩等公司6个岗位
点赞 评论 收藏
分享
05-09 12:23
已编辑
华南理工大学 Java
野猪不是猪🐗:给他装的,双九+有实习的能看的上这种厂我直接吃⑨✌们拿它练练面试愣是给他整出幻觉了
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务