zoukankan      html  css  js  c++  java
  • 算法 识别有效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就是一个非法的掩码)

    输入描述:

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

    参考讨论;子网掩码这块不是很熟悉,感觉没有特别好的算法,看起来都有点暴力

    链接:https://www.nowcoder.com/questionTerminal/de538edd6f7e4bc3a5689723a7435682?f=discussion
    来源:牛客网

    Yac836作者

    这个问题注意一下几点

    1. 255.255.255.255 为非法子网掩码(题目的意思,实际这个掩码,也能用)
    2. 当子网掩码错误时,不在判断ip是否有效,错误直接加一, 进行下次循环
    3. 当一个ip属于ABCDE类中的一个时候,也属于私有ip时,私有ip和他属于的分类都应该加一

    解题的方法

    1. 判断子网掩码是否有效

      1. 通过判断是否为255.255.255.255 如果是的话,错误加一,继续下次循环
      2. 判断别的子网掩码是否正确。根据子网掩码二进制规律(开头为连续的1,然后为0),我们将子网掩码按位取反,然后加一,得到的新二进制位,然后我们通过判断二进制中1的个数来判断是否为合法的子网掩码。(因为合法的子网掩码,按位取反,加一后,二进制位中,只有一个1)
        int validMask(char *p) {
        int flag,i ;
        unsigned int b1 = 0, n[4];
        sscanf(p, "%u.%u.%u.%u", &n[3], &n[2], &n[1], &n[0]);
        if(n[0] == 255 &&n[1] == 255 &&n[2] == 255 &&n[3] == 255 ) {
        flag = false;
        return flag;
        }
        for(i = 0; i < 4; ++i)
        b1 += n[i] << (i * 8);
        b1 = ~b1 + 1;
        if((b1 & (b1 - 1)) == 0) {
        flag = true;
        } else
        flag = false;
        return flag;
        }
    2. 判断ip时候有效,我们可以通过网络编程中自带的函数进行判断

      #include <arpa/inet.h>
      int inet_pton(int family, const char *strptr, void *addrptr);
                  返回:若成功则为1,若输入不是有效的表达格式则为0,若出错则为-1
    3. 如果ip地址有效,我们就可以判断它属于哪一类,是否是私有ip
    4. 完整代码


    #include <stdio.h> #include <arpa/inet.h> #include <sys/socket.h> #include <netinet/in.h> #include <strings.h> #include <stdlib.h> #include <string.h> #define true 1 #define false 0 int validMask(char *p) { int flag,i ; unsigned int b1 = 0, n[4]; sscanf(p, "%u.%u.%u.%u", &n[3], &n[2], &n[1], &n[0]); if(n[0] == 255 &&n[1] == 255 &&n[2] == 255 &&n[3] == 255 ) { flag = false; return flag; } for(i = 0; i < 4; ++i) b1 += n[i] << (i * 8); b1 = ~b1 + 1; if((b1 & (b1 - 1)) == 0) { flag = true; } else flag = false; return flag; } int main() { char str[50]; int a =0, b = 0, c = 0, d = 0, e = 0, err = 0, pri = 0; while(fgets(str,50,stdin)) { char *tok = str; char p[2][20] = {0}; int i = 0; while ((tok = strtok(tok, "~")) != NULL) { strcpy(p[i], tok); tok = NULL; i ++ ; if(i == 2) i = 0; } int flag = validMask(p[1]); if(flag) { struct in_addr s; unsigned int ip1,ip2; int valid = inet_pton(AF_INET,p[0],(void *)&s); sscanf(p[0],"%u.%u",&ip1,&ip2); if(valid) { if(ip1>=1 && ip1 <=126) a++; else if(ip1>=128 && ip1 <=191) b++; else if(ip1>=192 && ip1 <=223) c++; else if(ip1>=224 && ip1 <=239) d++; else if(ip1>=240 && ip1 <=255) e++; if(ip1==10 || (ip1==172 && ip2 >=16 &&ip2 <=31) || (ip1==192 && ip2 ==168)) pri ++; } else err ++; } else err++; } printf("%d %d %d %d %d %d %d ",a,b,c,d,e,err,pri); return 0; }

    C里面net去解,想法很不错,不熟悉仅做参考学习。
  • 相关阅读:
    606. Construct String from Binary Tree
    696. Count Binary Substrings
    POJ 3255 Roadblocks (次短路)
    POJ 2823 Sliding Window (单调队列)
    POJ 1704 Georgia and Bob (博弈)
    UVa 1663 Purifying Machine (二分匹配)
    UVa 10801 Lift Hopping (Dijkstra)
    POJ 3281 Dining (网络流之最大流)
    UVa 11100 The Trip, 2007 (题意+贪心)
    UVaLive 4254 Processor (二分+优先队列)
  • 原文地址:https://www.cnblogs.com/liuruoqian/p/11656571.html
Copyright © 2011-2022 走看看