C++判断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。(例如:255.255.255.32就是一个非法的掩码)
注意二进制下全是1或者全是0均为非法
注意:

  1. 类似于【0.*.*.*】【127.*.*.*】的IP地址不属于上述输入的任意一类,也不属于不合法ip地址,计数时可以忽略
  2. 私有IP地址和A,B,C,D,E类地址是不冲突的。

输入描述:
多行字符串。每行一个IP地址和掩码,用~隔开。
输出描述:
统计A、B、C、D、E、错误IP地址或错误掩码、私有IP的个数,之间以空格隔开。
示例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


题意理解:

  1. 做题过程中发现题目中隐含条件:子网掩码错误的情况下,不用进行ip地址的检测与分类,直接错误类加1;
  2. 类似于【0...】和【127...】的IP地址不用管,直接忽略好了;
  3. 私有IP地址和A,B,C,D,E类地址不冲突,隐含意思是一个ip地址如果既是A类,又是私有地址,则对应的两类计数都要加1;
  4. 二进制下子网掩码全是1或者全是0,则该子网掩码看作非法的,这与计算机网络中的介绍有出路,但是还是按照题意走;

1. 解题思路1:全用正则表达式

#include<iostream>
#include<string>
#include<regex>
#include<algorithm>
using namespace std;

int ipa,ipb,ipc,ipd,ipe,error,privateIp;

void isIp(string ip)
{
    regex patternA("(?:[1-9]|[1-9][0-9]|1[01][0-9]|12[0-6])(?:\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}");
    regex patternB("((12[8-9]|1[3-8][0-9]|19[0-1])(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3})");
    regex patternC("((19[2-9]|2[0-1][0-9]|22[0-3])(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3})");
    regex patternD("(22[4-9]|23[0-9])(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}");
    regex patternE("(24[0-9]|25[0-5])(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}");
    regex patternP("((10\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))|(172\.(1[6-9]|2[0-9]|3[0-1]))|(192\.168))(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){2}");
 
    smatch res;
    bool f=false; //f用来标志是否存在ip地址既不属于ABCDE,也不属于私有ip地址,如果存在,则错误类加1
     // A、B、C、D、E是互相冲突的,因此可以使用if...else结构,但是私有ip地址的判断不能用在if...else结构中
    if(regex_match(ip,res,patternA)){
        ++ipa;
        f=true;
    }
    else if(regex_match(ip,res,patternB)){
        ++ipb;
        f=true;
    }
    else if(regex_match(ip,res,patternC)){
        ++ipc;
        f=true;
    }
    else if(regex_match(ip,res,patternD)){
        ++ipd;
        f=true;
    }
    else if(regex_match(ip,res,patternE)){
        ++ipe;
        f=true;
    }
    if(regex_match(ip,res,patternP)){ //判断是否私有ip地址
        ++privateIp;
        f=true;
    }
    if(!f){
        ++error;
    }
}

bool isMask(string mask)
{
    regex patternM("((255|254|252|248|240|224|192|128)(\.0){3})|(255\.(255|254|252|248|240|224|192|128)(\.0){2})|(255\.255\.(255|254|252|248|240|224|192|128)\.0)|(255\.255\.255\.(254|252|248|240|224|192|128))");
    smatch res;
    if(regex_match(mask,res,patternM)){
        return true;
    }
    else{
        ++error;
        return false;
    }
}

int main(int argc,char **argv)
{
    string s;
    string ip;
    string mask;
    while(getline(cin,s)){
        int index = s.find("~");
        ip=s.substr(0,index);
        mask=s.substr(index+1); 

        string ip1=ip.substr(0,ip.find('.'));
        string mask1=mask.substr(0,mask.find('.'));
        if(isMask(mask)){
            if(ip1!="0" && ip1!="127") isIp(ip);
        }
    }
    cout<<ipa<<" "<<ipb<<" "<<ipc<<" "<<ipd<<" "<<ipe<<" "<<error<<" "<<privateIp<<endl;
    return 0;
}

正则表达式居然只能ac 90%,原因是超时,难受!难道正则表达式的处理效率比一般的字符串处理函数效率低吗?这个要怎么测试:(

2. 解题思路2:正则表达式与普通的字符串处理函数结合

#include<iostream>
#include<string>
#include<regex>
 
using namespace std;
int ipa,ipb,ipc,ipd,ipe,error,privateIp;
 
bool isMask(string mask)
{
    regex patternM("((255|254|252|248|240|224|192|128)(\.0){3})|(255\.(255|254|252|248|240|224|192|128)(\.0){2})|(255\.255\.(255|254|252|248|240|224|192|128)\.0)|(255\.255\.255\.(254|252|248|240|224|192|128))");
    smatch res;
    if(regex_match(mask,res,patternM)){
        return true;
    }
    else{
        ++error;
        return false;
    }
    return false;
}
 
bool isNip(string ip)
{
    regex pattern("(0|127)(.)*");
    smatch res;
    if(regex_match(ip,res,pattern)){
        return true;
    }
    return false;
}

//判断ip地址是否有效 
bool isIp(string ip)
{
    regex patternIP("((2[0-5][0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(2[0-5][0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)");
    smatch res;
    if(regex_match(ip,res,patternIP)){
        return true;
    }
    else{
        ++error;
        return false;
    }
    return true;
}

//分类ip地址并统计各个类别的数量
void ipClass(string ip)
{
    int index = ip.find('.');
    int ip1=stoi(ip.substr(0,index));
    int ip2=stoi(ip.substr(index+1,ip.find('.',index+1)-index-1));
    if(ip1>=1 && ip1<=126){
        ++ipa;
        if(ip1==10){
            ++privateIp;
        }
    }
    else if(ip1>=128 && ip1<=191){
        ++ipb;
        if(ip1==172 &&(ip2>=16 && ip2<=31)){
            ++privateIp;
        }
    }
    else if(ip1>=192 && ip1<=223){
        ++ipc;
        if(ip1==192 && ip2==168){
            ++privateIp;
        }
    }
    else if(ip1>=224 && ip1<=239){
        ++ipd;
    }
    else if(ip1>=240 && ip1<=255){
        ++ipe;
    }
}
 
int main(int argc,char **argv)
{
    string s;
    string ip;
    string mask;
    while(getline(cin,s)){
        int index = s.find('~');
        ip = s.substr(0,index);
        mask = s.substr(index+1);
        // cout<<ip<<" "<<mask<<endl;
        if(isMask(mask) && !isNip(ip) &&isIp(ip)){
            //对ip分类并统计
            ipClass(ip);
        }
    }
    cout<<ipa<<" "<<ipb<<" "<<ipc<<" "<<ipd<<" "<<ipe<<" "<<error<<" "<<privateIp<<endl;
    return 0;
}

这个是全ac的。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 221,820评论 6 515
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,648评论 3 399
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 168,324评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,714评论 1 297
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,724评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,328评论 1 310
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,897评论 3 421
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,804评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,345评论 1 318
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,431评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,561评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,238评论 5 350
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,928评论 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,417评论 0 24
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,528评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,983评论 3 376
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,573评论 2 359