[华为机试练习题]34.识别有效的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

题目类别:

字符串

难度:

    中级

运行时间限制:

    10Sec

内存限制:

    128MByte

阶段:

入职前练习

输入:

多行字符串。每行一个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

代码

/*---------------------------------------
*   日期:2015-07-02
*   作者:SJF0115
*   题目:识别有效的IP地址和掩码并进行分类统计
*   来源:华为机试练习题
-----------------------------------------*/
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <list>
using namespace std;

// 检查子网掩码和IP格式是否正确 并返回分段
bool isRight(string str,vector<string> &part){
    int size = str.size();
    int pointCount = 0;
    string::size_type index = 0;
    int prePoint = 0;
    while((index = str.find_first_of(‘.‘,index)) != string::npos){
        //..之间有数字
        if(index != prePoint){
            part.push_back(str.substr(prePoint,index-prePoint));
        }//if
        ++index;
        prePoint = index;
        ++pointCount;
    }//while
    if(prePoint < size){
        part.push_back(str.substr(prePoint));
    }//if

    int partSize = part.size();
    if(partSize != 4){
        return false;
    }//if

    // 判断每一部分均属于0-255
    int num;
    for(int i = 0;i < partSize;++i){
        num = atoi(part[i].c_str());
        if(num < 0 || num > 255){
            return false;
        }//if
    }//for
    // 代表错误IP
    if(pointCount != 3){
        return false;
    }//if
    return true;
}

// 检查IP
bool CheckIP(string ip,vector<int> &count){
    vector<string> part;
    // 格式不正确
    bool result = isRight(ip,part);
    if(!result){
        return false;
    }//if
    // 判断IP分类
    int num = atoi(part[0].c_str());
    if(num >= 1 && num <= 126){
        ++count[0];
    }//if
    else if(num >= 128 && num <= 191){
        ++count[1];
    }//else
    else if(num >= 192 && num <= 223){
        ++count[2];
    }//else
    else if(num >= 224 && num <= 239){
        ++count[3];
    }//else
    else if(num >= 240 && num <= 255){
        ++count[4];
    }//else
    else if(num == 127){
        return false;
    }
    // 私有IP
    int num1 = atoi(part[1].c_str());
    if(num==10||(num==172&&num1>=16&&num1<=31)||(num==192&&num1==168)){
        ++count[6];
    }//else
    return true;
}
// 判断是否是子网掩码
bool isNet(vector<string> part){
    int number[] = {0,128,192,224,240,248,252,254};
    int size = part.size();
    int num;
    bool flag = false;
    bool isOk = false;
    for(int i = 0;i < size;++i){
        num = atoi(part[i].c_str());
        if(flag && num != 0){
            return false;
        }//if
        else if(num != 255){
            flag = true;
            // 判断左边是不是全为1右边全为0
            for(int j = 0;j < 8;++j){
                if(num == number[j]){
                    isOk = true;
                    break;
                }//if
            }//for
            if(!isOk){
                return false;
            }//if
        }//if
    }//for
    return true;
}
// 检查子网掩码
bool CheckNet(string net){
    vector<string> part;
    bool result = isRight(net,part);
    if(!result){
        return false;
    }//if
    // 判断是否是子网掩码
    result = isNet(part);
    return result;
}

int main(){
    int n;
    string str;
    //freopen("C:\\Users\\Administrator\\Desktop\\c++.txt","r",stdin);
    int index;
    string ip,net;
    vector<int> count(7,0);
    while(getline(cin,str)){
        index = str.find("~",0);
        ip = str.substr(0,index);
        net = str.substr(index+1);

        bool resultNet = CheckNet(net);
        bool resultIP = false;
        if(resultNet){
            resultIP = CheckIP(ip,count);
        }//if

        if(!resultIP || !resultNet){
            count[5] += 1;
        }//if
    }//while
    for(int i = 0;i < 7;++i){
        if(i == 0){
            cout<<count[i];
        }//if
        else{
            cout<<" "<<count[i];
        }//else
    }//for
    cout<<endl;
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-03 21:50:46

[华为机试练习题]34.识别有效的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

[华为机试练习题]44.24点游戏算法

题目 注意: 6 + 2 * 4 + 10 = 24 不是一个数字一个数字的计算 代码 /*--------------------------------------- * 日期:2015-07-03 * 作者:SJF0115 * 题目:24点游戏算法 * 来源:华为机试练习题 -----------------------------------------*/ #include <iostream> #include <string> #include <vector&

[华为机试练习题]45.求某二进制数中1的个数

题目 描述: 题目标题: 求某二进制数中1的个数. 给定一个unsigned int型的正整数,求其二进制表示中"1"的个数,要求算法的执行效率尽可能地高. 详细描述: 原型: int GetCount(unsigned int num) 输入参数: num 给定的正整数 输出参数(指针指向的内存区域保证有效): 无 返回值: 返回1的个数 举例: 输入13,则对应的二进制是1101,那么1的个数为3个.则:返回3. 练习阶段: 初级 代码 /*--------------------

[华为机试练习题]46.计算二进制数的0的个数

题目 描述: 输入一个10进制数字,请计算该数字对应二进制中0的个数,注意左数第一个1之前的所有0都不需要计算.不需要考虑负数的情况. 题目类别: 位运算 难度: 初级 运行时间限制: 无限制 内存限制: 无限制 阶段: 入职前练习 输入: 要计算的十进制非负数 输出: 二进制中第一个1之后0 的个数 样例输入: 2 样例输出: 1 代码 /*--------------------------------------- * 日期:2015-07-03 * 作者:SJF0115 * 题目:计算二

[华为机试练习题]58.查找同构数的数量

题目 描写叙述: 找出1至n之间同构数的个数. 同构数是这样一组数:它出如今平方数的右边.比如:5是25右边的数.25是625右边的数,5和25都是同构数. 具体描写叙述: 接口说明 原型: intSearchSameConstructNum(int n); 输入參数: int n:查找1至n之间的所有同构数 返回值: int:1至n之间同构数的个数 练习阶段: 0基础 代码 /*--------------------------------------- * 日期:2015-07-05 *

[华为机试练习题]57.对象管理器

题目 代码 /*--------------------------------------- * 日期:2015-07-05 * 作者:SJF0115 * 题目:对象管理器 * 来源:华为机试练习题 -----------------------------------------*/ #include <iostream> #include "ObjMgt.h" #include <vector> using namespace std; struct Ob

[华为机试练习题]1.周期串问题

题目一[周期串问题] 如果一个字符串可以由某个长度为k的字符串重复多次得到,我们说该串以k为周期.例如,abcabcabcabc以3为周期(注意,它也可以6和12为周期,结果取最小周期3).字符串的长度小于等于100,由调用者保证. 接口说明 原型: int GetMinPeriod(char *inputstring); 输入参数: char * inputstring:字符串 返回值: int 字符串最小周期 代码一 /*-----------------------------------

[华为机试练习题]24.删除链表中的反复节点、剩余节点逆序输出

题目 描写叙述: 题目描写叙述: 输入一个不带头节点的单向链表(链表的节点数小于100),删除链表中内容反复的节点(反复的节点所有删除),剩余的节点逆序倒排. 要求实现函数: void vChanProcess(strNode * pstrIn,strNode * pstrOut); [输入] pstrIn:输入一个不带头节点的单向链表 [输出] pstrOut:删除内容反复的节点(反复的节点所有删除).剩余节点逆序输出(不带头节点,链表第一个节点的内存已经申请). [注意]仅仅须要完毕该函数功

[华为机试练习题]56.求子数组的最大和

题目 描述: 输入一个整形数组.数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和.求所有子数组的和的最大值. 接口 Int GetSubArraySum(Int* pIntArray,Int nCount): 规格 要求时间复杂度为O(n) 举例 例如输入的数组为1, -2, 3, 10, -4, 7, 2, -5,和最大的子数组为3, 10, -4, 7, 2, 因此输出为该子数组的和18 练习阶段: 初级 代码 /*-------------------------------