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

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

using namespace std;

// 将IP地址字符串转换为4个整数的数组
bool parseIP(const string& ip, int* ipParts) {
    stringstream ss(ip);
    string part;
    for (int i = 0; i < 4; ++i) {
        if (!getline(ss, part, '.')) return false;
        if (part.empty() ||
                part.find_first_not_of("0123456789") != string::npos) return false;
        ipParts[i] = stoi(part);
        if (ipParts[i] < 0 || ipParts[i] > 255) return false;
    }
    return true;
}

// 检查子网掩码是否合法
bool isValidSubnetMask(const int* mask) {
    bool hasZero = false;
    for (int i = 0; i < 4; ++i) {
        for (int j = 7; j >= 0; --j) {
            bool bit = (mask[i] >> j) & 1;
            if (bit == 0) hasZero = true;
            else if (hasZero) return false; // 1 after 0 is invalid
        }
    }
    // 全0或全1的掩码也是非法的
    if (!hasZero || (mask[0] == 255 && mask[1] == 255 && mask[2] == 255 &&
                     mask[3] == 255)) return false;
    return true;
}

// 判断IP地址的类别
char getIPClass(const int* ip) {
    if (ip[0] >= 1 && ip[0] <= 126) return 'A';
    if (ip[0] >= 128 && ip[0] <= 191) return 'B';
    if (ip[0] >= 192 && ip[0] <= 223) return 'C';
    if (ip[0] >= 224 && ip[0] <= 239) return 'D';
    if (ip[0] >= 240 && ip[0] <= 255) return 'E';
    return 'X'; // 不属于任何类别
}

// 判断是否为私有IP
bool isPrivateIP(const int* ip) {
    if (ip[0] == 10) return true;
    if (ip[0] == 172 && (ip[1] >= 16 && ip[1] <= 31)) return true;
    if (ip[0] == 192 && ip[1] == 168) return true;
    return false;
}

int main() {
    int countA = 0, countB = 0, countC = 0, countD = 0, countE = 0;
    int countError = 0, countPrivate = 0;

    string line;
    while (getline(cin, line)) {
        stringstream ss(line);
        string ipStr, maskStr;
        getline(ss, ipStr, '~');
        getline(ss, maskStr);

        int ip[4], mask[4];
        if (!parseIP(ipStr, ip) || !parseIP(maskStr, mask)) {
            countError++;
            continue;
        }

        // 特殊IP地址(0.*.*.* 和 127.*.*.*)不处理
        if (ip[0] == 0 || ip[0] == 127) continue;

        // 检查子网掩码是否合法
        if (!isValidSubnetMask(mask)) {
            countError++;
            continue;
        }

        // 判断IP类别
        char ipClass = getIPClass(ip);
        switch (ipClass) {
            case 'A':
                countA++;
                break;
            case 'B':
                countB++;
                break;
            case 'C':
                countC++;
                break;
            case 'D':
                countD++;
                break;
            case 'E':
                countE++;
                break;
            default:
                break;
        }

        // 判断是否为私有IP
        if (isPrivateIP(ip)) countPrivate++;
    }

    cout << countA << " " << countB << " " << countC << " " << countD << " " <<
         countE << " "
         << countError << " " << countPrivate << endl;

    return 0;
}

全部评论

相关推荐

不愿透露姓名的神秘牛友
07-23 14:13
这是聊岔撇了吗,相同的话问了两遍
吴offer选手:上下文切换这一块
点赞 评论 收藏
分享
07-22 11:35
门头沟学院 Java
谁知道这是为什么吗,有没有懂的佬给讲讲
理智的小饼干又熬夜了:鹅打电话问我参不参加后台提前批,说是有的但还没放官网
点赞 评论 收藏
分享
机械打工仔:不管啥专业,找工作改简历的第一课先把你那排版改了,简历上不要写个人简历四个字,找你要简历的谁不知道这个是简历?而且还占那么多空间,直接把自己名字和基础信息写上面,整体字体大一些。 还有这种经典两页简历一页大空白,导出PDF的时候多了一页几乎全是白的你自己看着不难受吗随手的事为啥不能改掉呢,这是态度问题,你试想一下你是HR你打开简历看到格式都没调整过会是什么感受?你自己都不重视你的简历,HR更不会在意。 然后内容你那个做两年咖啡就别往里写了,简历在精不在多,你在往你的简历里打字的时候就要想好这东西对你要找的工作有没有帮助。自我评价写一行就行了,不如给专业技能单开一栏。核心课程均分90这个真别写了,把你上过的有用的专业课列出来也行。有很多地方废话很多的精炼一下,比如你校内项目第一个写的那些,全然没有重点。 好好修改一下,我看你内容也挺优秀的,别被一个随便做的简历耽误了,我一个同专业的打工人看了都揪心更别说一天看几百份简历的HR
听劝,我这个简历该怎么改...
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务