【华为练习题】识别IP地址与掩码(中级)

该博客介绍了华为中级练习题,涉及识别和分类IP地址与掩码,包括A、B、C、D、E五类地址,以及私网IP和错误情况。通过示例输入和输出,解释了如何统计各类IP和错误的情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【华为练习题】识别IP地址与掩码(中级)

题目

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

描述: 请解析IP地址和对应的掩码,进行分类识别。要求按照A/B/C/D/E类地址归类,不合法的地址和掩码单独归类。

所有的IP地址划分为 A,B,C,D,E五类

A类地址1.0.0.0~126.255.255.255;

B类地址128.0.0.0~191.255.255.255;

C类地址192.0.0.0~223.255.255.255;

D类地址224.0.0.0~239.255.255.255;

E类地址240.0.0.0~255.255.255.255

私网IP范围是:

10.0.0.0~10.255.255.255

172.16.0.0~172.31.255.255

192.168.0.0~192.168.255.255

子网掩码为前面是连续的1,然后全是0

输入:
多行字符串。每行一个IP地址和掩码,已~隔开。如:

10.70.44.68~255.254.255.0

1.0.0.1~255.0.0.0

192.168.0.2~255.255.255.0

19..0.~255.255.255.0

输出:
统计A、B、C、D、E、错误IP地址或错误掩码、私有IP的个数,之间以空格隔开,根据上面的IP,可以得到:

1.0.0.1~255.0.0.0 —-A类

192.168.0.2~255.255.255.0 —-C类,私有

10.70.44.68~255.254.255.0—-错误的掩码

19..0.~255.255.255.0—–错误的IP

可以得到统计数据如下:

1 0 1 0 0 2 1

样例输入: 10.70.44.68~255.254.255.0
1.0.0.1~255.0.0.0
192.168.0.2~255.255.255.0
19..0.~255.255.255.0

样例输出: 1 0 1 0 0 2 1

解答

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

// 检查字符串是否合法,并将字符串转化为整型数组
bool convert(string const &s, vector<int> &v){
    auto begin = s.begin();
    while (begin != s.end())
    {
        if (!isdigit(*begin)) return false;
        auto ahead = begin + 1;
        while (ahead != s.end() && *ahead != '.')
        {
            if (!isdigit(*ahead)) return false;
            ahead++;
        }
        int value = stoi(string(begin, ahead));
        if (value > 255) return false;
        v.push_back(value);
        begin = ahead;
        if (ahead != s.end()) ++begin;
    }
    if (v.size() != 4) return false;
    return true;
}

// 检查掩码地址是否合法
bool isRight(vector<int> const &v){
    bool flag = true;
    for (int i = 0; i < 4; i++)
    {
        int tmp = v[i];
        if ((tmp == 255 && flag) || (tmp == 0 && !flag)) continue;
        if (tmp != 0 && !flag) return false;
        int cmp = 1 << 7;
        int times = 8;
        while (times--)
        {
            if (tmp & cmp)
            {
                tmp <<= 1;
                continue;
            }
            flag = false;
            break;
        }
        if (tmp & 255) return false;
    }
    return true;
}

void judge(vector<string> const &v, vector<int> &result){
    for (auto begin = v.begin(); begin != v.end(); ++begin){
        string s = *begin;
        auto pos = find(s.begin(), s.end(), '~');
        if (pos == s.end()){
            result[5]++;
            continue;
        }
        vector<int> ip, code;
        if (!convert(string(s.begin(), pos), ip) || !convert(string(pos + 1, s.end()), code) || !isRight(code))
        {
            result[5]++;
            continue;
        }
        vector<int> net;
        for (unsigned i = 0; i < 4; i++)
        {
            net.push_back(ip[i] & code[i]);
        }
        if (net[0] <= 126)
        {
            result[0]++;
            if (net[0] == 10) result[6]++;
        }
        else if (net[0] == 127)
        {
            result[5]++;
            continue;
        }
        else if (net[0] <= 191)
        {
            result[1]++;
            if (net[0] == 172 && net[1] >= 16 && net[1] <= 31) result[6]++;
        }
        else if (net[0] <= 223)
        {
            result[2]++;
            if (net[0] == 192 && net[1] == 168) result[6]++;
        }
        else if (net[0] <= 239)
        {
            result[3]++;
        }
        else
        {
            result[4]++;
        }
    }
}

int main(){
    string s;
    vector<string> v;
    vector<int> result(7,0);
    while (cin >> s)
    {
        v.push_back(s);
    }
    judge(v,result);
    for (int i = 0; i < 7; i++)
    {
        cout << result[i] << " ";
    }
    cout << endl;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值