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

//#include <bits/stdc++.h>
#include <iostream>
#include <string>
#include <sstream>
#include <vector>

using namespace std;

//判断ip
/*判断IP地址是否合法,如果满足下列条件之一即为非法地址
数字段数不为4
存在空段,即【192..1.0】这种
某个段的数字大于255
*/
bool judgeIP(string s){
    int count = 0;
    stringstream iss(s);
    string tmp = "";
    while(getline(iss, tmp, '.')){
        if(++count > 4 || tmp.empty() || stoi(tmp) > 255){
            return false;
        }
    }
    return count == 4;
}

//判断是否私有
bool isPrivate(string s){
    stringstream iss(s);
    string tmp = "";
    vector<int> vec;
    while(getline(iss, tmp, '.')){
        vec.push_back(stoi(tmp));
    }
    
    if(vec[0] == 10) return true;
    if(vec[0] == 172 && (vec[1] >= 16 && vec[1] <= 31)) return true;
    if(vec[0] == 192 && vec[1] == 168) return true;
    return false;
}

//判断掩码
/*
判断子网掩码是否合法,如果满足下列条件之一即为非法掩码
不是一个合格的IP地址
在二进制下,不满足前面连续是1,然后全是0
在二进制下,全为0或全为1

如何判断一个掩码地址是不是满足前面连续是1,然后全是0?
将掩码地址转换为32位无符号整型,假设这个数为b。如果此时b为0,则为非法掩码
将b按位取反后+1。如果此时b为1,则b原来是二进制全1,非法掩码
如果b和b-1做按位与运算后为0,则说明是合法掩码,否则为非法掩码
*/
bool judgeMask(string s){
    stringstream iss(s);
    string tmp = "";
    unsigned int val = 0;
    while(getline(iss, tmp, '.')){
        val = (val << 8) + stoi(tmp); //拿到子网掩码的32位无符号整形值  
    }
    //cout << "val" << val << endl;
    if(val == 0) return false; //全为0
    if(~val + 1 == 1) return false; //全为1
    if((val | (val - 1)) == 0xFFFFFFFF) return true; //全面连续1,后面连续0
    //if((val & (val - 1)) == 0) return true;
    return false;
}

int main(){
    string str = "";
    int a = 0, b = 0, c = 0, d = 0, e = 0, err = 0, p = 0;
    while(cin >> str){
        stringstream iss(str);
        string tmp = "";
        vector<string> vec;
        while(getline(iss, tmp, '~')){
            vec.push_back(tmp);//按行读取输入,根据字符‘~’ 将IP地址与子网掩码分开
        }
        //cout<<vec[0]<<" "<<vec[1]<<endl;
        int first = stoi(vec[0].substr(0, vec[0].find_first_of('.')));
        //查看子网掩码是否合法
        if((first != 127) && (!judgeIP(vec[0]) || !judgeMask(vec[1]))) err++; //多加first != 127的判断(否则会多加一次err)
        else{//合法,则继续检查IP地址          
            //查看IP地址是否合法
            if(!judgeIP(vec[0])) err++;//非法,相应统计项+1
            else{//合法,查看IP地址属于哪一类,是否是私有ip地址;相应统计项+1
                if(isPrivate(vec[0])) p++;
                             
                if(first == 0 || first == 127) continue;
                else if(first >= 1 && first <= 126) a++;
                else if(first >= 128 && first <= 191) b++;
                else if(first >= 192 && first <= 223) c++;
                else if(first >= 224 && first <= 239) d++;
                else if(first >= 240 && first <= 255) e++;
            }         
        }
    }
    
    cout << a << " " << b << " " << c << " " << d << " " << e << " " << err << " " << p << endl;
    
    return 0;
}
全部评论

相关推荐

程序员牛肉:主要是因为小厂的资金本来就很吃紧,所以更喜欢有实习经历的同学。来了就能上手。 而大厂因为钱多,实习生一天三四百的就不算事。所以愿意培养你,在面试的时候也就不在乎你有没有实习(除非是同级别大厂的实习。) 按照你的简历来看,同质化太严重了。项目也很烂大街。 要么换项目,要么考研。 你现在选择工作的话,前景不是很好了。
点赞 评论 收藏
分享
04-02 16:49
门头沟学院 Java
_bloodstream_:我也面了科大讯飞,主管面的时候听说急招人优先考虑能尽快实习的,我说忙毕设,后面就一直没消息了
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务