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

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

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

#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <bitset>
using namespace std;


int isSub(string sub) {
    //判断子网掩码是否正确
    stringstream ss(sub);
    string t;
    int first_1 = 0;
    int first_0 = 0;
    while (getline(ss, t, '.')) {
        if (t.size() == 0) {
            return 0;
        }
        int num = stoi(t);
        bitset<8> bin_n(num);
        string bins = bin_n.to_string();
        for (int i = 0; i < 8; i++) {
            if ((!first_1 && bins[i] == '0') || (first_0 && bins[i] == '1'))
                return 0;
            else if (!first_1 && bins[i] == '1') {
                first_1 = 1;
            } else if (first_1 && !first_0 && bins[i] == '0') {
                first_0 = 1;
            }
        }
    }
    if (first_0 == 0 || first_1 == 0)
        return 0;
    else
        return 1;
}

//返回-1  表示子网掩码错误, 返回 0 表示不是A类地址, 返回1 表示是A类地址
int isNetA(string addr, string sub) {
    int low[] = {1, 0, 0, 0};
    int top[] = {126, 255, 255, 255};
    int lowp[] = {10, 0, 0, 0};
    int topp[] = {10, 255, 255, 255};
    //先判断子网掩码是否正确
    if (!isSub(sub))
        return -1;
    stringstream ss(addr);
    string t;
    int idx = 0;
    int isPriv = 1;
    while (getline(ss, t, '.')) {
        if (t.size() == 0) {
            return -1;
        }
        int num = stoi(t);
        if (num < 0)
            return -1;
        if (num < low[idx] || num > top[idx]) {
            return 0;
        }
        if (isPriv && (num < lowp[idx] || num > topp[idx])) {
            isPriv = 0;
        }
        idx += 1;
    }
    if (isPriv)
        return 2;
    return 1;

}

//返回-1  表示子网掩码错误, 返回 0 表示不是B类地址, 返回1 表示是B类地址
int isNetB(string addr, string sub) {
    int low[] = {128, 0, 0, 0};
    int top[] = {191, 255, 255, 255};
    int lowp[] = {172, 16, 0, 0};
    int topp[] = {172, 31, 255, 255};
    //先判断子网掩码是否正确
    if (!isSub(sub))
        return -1;
    stringstream ss(addr);
    string t;
    int idx = 0;
    int isPriv = 1;
    while (getline(ss, t, '.')) {
        if (t.size() == 0) {
            return -1;
        }
        int num = stoi(t);
        if (num < 0)
            return -1;
        if (num < low[idx] || num > top[idx]) {
            return 0;
        }
        if (isPriv && (num < lowp[idx] || num > topp[idx])) {
            isPriv = 0;
        }
        idx += 1;
    }
    if (isPriv)
        return 2;
    return 1;

}


//返回-1  表示子网掩码错误, 返回 0 表示不是C类地址, 返回1 表示是C类地址
int isNetC(string addr, string sub) {
    int low[] = {192, 0, 0, 0};
    int top[] = {223, 255, 255, 255};
    int lowp[] = {192, 168, 0, 0};
    int topp[] = {192, 168, 255, 255};
    //先判断子网掩码是否正确
    if (!isSub(sub))
        return -1;
    stringstream ss(addr);
    string t;
    int idx = 0;
    int isPriv = 1;
    while (getline(ss, t, '.')) {
        if (t.size() == 0) {
            return -1;
        }
        int num = stoi(t);
        if (num < 0)
            return -1;
        if (num < low[idx] || num > top[idx]) {
            return 0;
        }
        if (isPriv && (num < lowp[idx] || num > topp[idx])) {
            isPriv = 0;
        }
        idx += 1;
    }
    if (isPriv)
        return 2;
    return 1;

}
//返回-1  表示子网掩码错误, 返回 0 表示不是D类地址, 返回1 表示是D类地址
int isNetD(string addr, string sub) {
    int low[] = {224, 0, 0, 0};
    int top[] = {239, 255, 255, 255};
    //先判断子网掩码是否正确
    if (!isSub(sub))
        return -1;
    stringstream ss(addr);
    string t;
    int idx = 0;
    while (getline(ss, t, '.')) {
        if (t.size() == 0) {
            return -1;
        }
        int num = stoi(t);
        if (num < 0)
            return -1;
        if (num < low[idx] || num > top[idx]) {
            return 0;
        }
        idx += 1;
    }
    return 1;

}

//返回-1  表示子网掩码错误, 返回 0 表示不是E类地址, 返回1 表示是E类地址
int isNetE(string addr, string sub) {
    int low[] = {240, 0, 0, 0};
    int top[] = {255, 255, 255, 255};
    //先判断子网掩码是否正确
    if (!isSub(sub))
        return -1;
    stringstream ss(addr);
    string t;
    int idx = 0;
    while (getline(ss, t, '.')) {
        if (t.size() == 0) {
            return -1;
        }
        int num = stoi(t);
        if (num < 0)
            return -1;
        if (num < low[idx] || num > top[idx]) {
            return 0;
        }
        idx += 1;
    }
    return 1;

}

int main() {
    //
    int an = 0;
    int bn = 0;
    int cn = 0;
    int dn = 0;
    int en = 0;
    int errn = 0;
    int pn = 0;
    string str;
    while (getline(cin, str)) {
        stringstream ss(str);
        vector<string> tokens;
        string t;
        while (getline(ss, t, '~')) {
            if (t.size() == 0) {
                continue;
            }
            tokens.push_back(t);
        }
        if(tokens[0].substr(0, tokens[0].find('.'))=="0" || tokens[0].substr(0, tokens[0].find('.'))=="127")
            continue;
        
        int resa = isNetA(tokens[0], tokens[1]);
        if(resa == 2){
            //cout << "resa==2 : " << tokens[0] << "~" <<tokens[1] << endl;
            an ++; pn ++;
            continue;
        }else if(resa == 1){
            //cout << "resa==1 : " << tokens[0] << "~" <<tokens[1] << endl;
            an ++;
            continue;
        }
        int resb = isNetB(tokens[0], tokens[1]);
        if(resb == 2){
            //cout << "resb==2 : " << tokens[0] << "~" <<tokens[1] << endl;
            bn ++; pn ++;
            continue;
        }
        else if(resb == 1){
            //cout << "resb==1 : " << tokens[0] << "~" <<tokens[1] << endl;
            bn ++;
            continue;
        }
        int resc = isNetC(tokens[0], tokens[1]);
        if(resc == 2){
            //cout << "resc==2 : " << tokens[0] << "~" <<tokens[1] << endl;
            cn ++; pn ++;
            continue;
        }
        else if(resc == 1){
            //cout << "resc==1 : " << tokens[0] << "~" <<tokens[1] << endl;
            cn ++;
            continue;
        }

        int resd = isNetD(tokens[0], tokens[1]);
        if(resd == 1){
            //cout << "resd==1 : " << tokens[0] << "~" <<tokens[1] << endl;
            dn ++;
            continue;
        }
        int rese = isNetE(tokens[0], tokens[1]);
        if(rese == 1){
            //cout << "rese==1 : " << tokens[0] << "~" <<tokens[1] << endl;
            en ++;
            continue;
        }
        //cout << "error : " << tokens[0] << "~" <<tokens[1] << endl;
        errn ++;
    }
    cout << an << " " << bn << " " << cn << " " << dn << " " <<en << " " << errn << " " << pn;
    return 0;
}
// 64 位输出请用 printf("%lld")

可以将判断每个网络地址类型的函数写成一个,然后根据传入的地址范围进行判断

全部评论

相关推荐

头像
11-18 16:08
福州大学 Java
影流之主:干10年不被裁,我就能拿别人一年的钱了,日子有盼头了
点赞 评论 收藏
分享
accaacc:2到4k,不是2k到4k,所以年薪是30块
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务