题解 | java菜鸡的题解

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

http://www.nowcoder.com/practice/de538edd6f7e4bc3a5689723a7435682

题目描述

请解析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的个数,之间以空格隔开。


notes:

全零“0.0.0.0”或者全1  “255.255.255.255”的子网掩码也是非法的

过程:
1、判断输入的ip长度和数字区间是否合法 , 不合法则判定为非法ip,然后读下一行(即不对 本行数据进行其他判断了),如果合法则不进行任何操作,继续 2-4步骤
2、判断子网掩码是否合法,不合法则判定为非法ip,然后跳过这行数据,如果合法则不进行任何操作,继续 3-4步骤
3、判断ip属于哪一类ip(A-E)
4、判断ip是否为私有

具体实现(这部分摘自一个cpp大佬的,实在不想写了/233)

1、判断IP地址是否合法,如果满足下列条件之一即为非法地址

    数字段数不为4
    存在空段,即【192..1.0】这种
    某个段的数字大于255
2、判断子网掩码是否合法,如果满足下列条件之一即为非法掩码
    不是一个合格的IP地址
    在二进制下,不满足前面连续是1,然后全是0
    在二进制下,全为0或全为1
3、如何判断一个掩码地址是不是满足前面连续是1,然后全是0?
    将掩码地址转换为Long类型,假设这个数为b。如果此时b为0,则为非法掩码
    将b按位取反后+1。如果此时b为1,则b原来是二进制全1,非法掩码

    假设子网掩码ip为maskIP,如果满足((maskIP^ 0XFFFFFFFFL) + 1) | maskIP) == maskIP,则为子网掩码 ------  这个思路来自java排行榜上的思路

代码如下:

import java.util.*;

public class Main{
   
       private static Map<String,Integer> map = new HashMap<>();
    private static String[] helpString = new String[]{"category_A","category_B","category_C","category_D","category_E","illegalIP","privateIP","other"};
    public static void main(String[] args) {
        for (int i = 0; i < helpString.length; i++) {//将各类的数目初始化为0
            map.put(helpString[i], 0);
        }

        Scanner in = new Scanner(System.in);
        while (in.hasNextLine()) {
            String input = in.nextLine();
            if(input.length() == 0) break;
            String[] ipSegment = input.split("~");
            String[] ipAddress = ipSegment[0].split("\\.");
            String[] maskAddress = ipSegment[1].split("\\.");

//            for (String address : ipAddress) {
//                System.out.print(address + " ");
//            }
//            System.out.println();
//            System.out.println(ipAddress.length);

            //判断是否为非法的ip
            boolean judgeIllegal = isIllegal(ipAddress, maskAddress);
            if(!judgeIllegal){
                map.put("illegalIP",map.get("illegalIP") + 1);
                continue;
            }

            //判断子网掩码是否合法
            boolean judgeMaskIP = isMask(maskAddress);
            if(!judgeMaskIP){
                map.put("illegalIP",map.get("illegalIP") + 1);
                continue;
            }

            //判断ip是否为私有地址
            boolean judgePrivate = isPrivate(ipAddress);
            if(judgePrivate) map.put("privateIP",map.get("privateIP") + 1);

            //判断ip的类别
            String judgeCategory = judge_ip(ipAddress);
            map.put(judgeCategory,map.get(judgeCategory) + 1);
        }
            System.out.println(map.get(helpString[0]) + " " + map.get(helpString[1]) + " " + map.get(helpString[2]) + " " +map.get(helpString[3]) + " "
                    + map.get(helpString[4]) + " " + map.get(helpString[5]) + " " + map.get(helpString[6]));
            in.close();
    }



    public static boolean isIllegal (String[]ipAddress, String[]maskAddress){
        if (ipAddress.length != 4 || maskAddress.length != 4) return false;
        for (String temp : ipAddress) {
            long num = Long.parseLong(temp);
            if (num < 0 || num > 255) return false;
        }
        return true;
    }

    //mask -1 | mask) ==  0xFFFFFFFF ,如果是TRUE就是子网掩码,是FALSE就不是子网掩码。
    public static boolean isMask (String[]maskAddress){
        boolean flag = true;
        if (maskAddress.length != 4) return false;
        Long maskTemp = 0L;
        for(int i=0; i < maskAddress.length; i++){
            maskTemp = (maskTemp << 8) + Long.parseLong(maskAddress[i]);
        }

        //全0也判定为非法 掩码
        if (maskTemp == 0) {
            flag = false;
            return flag;
        }
        //全为1 则不是子网掩码
        Long tempMask = ~maskTemp + 1;
        if (tempMask == 1) {
            flag = false;
            return flag;
        }

//        String judgeMask = Long.toBinaryString(maskTemp);
        if(maskTemp <= 0 || maskTemp >=0XFFFFFFFFL || (((maskTemp ^ 0XFFFFFFFFL) + 1) | maskTemp)!= maskTemp){
            flag = false;
            return flag;
        }


        return flag;
    }
    //判断是否为私有地址
    public static boolean isPrivate (String[]ipAddress){
        long oneSegment = Long.parseLong(ipAddress[0]);
        long twoSegment = Long.parseLong(ipAddress[1]);
        if (oneSegment == 10) return true;
        if (oneSegment == 172 && (twoSegment >= 16 && twoSegment <= 31)) return true;
        if (oneSegment == 192 && twoSegment == 168) return true;
        return false;
    }

    public static String judge_ip (String[]ipAddress){
        long oneSegment = Long.parseLong(ipAddress[0]);
        if (oneSegment >= 1 && oneSegment <= 126) return helpString[0];
        if (oneSegment >= 128 && oneSegment <= 191) return helpString[1];
        if (oneSegment >= 192 && oneSegment <= 223) return helpString[2];
        if (oneSegment >= 224 && oneSegment <= 239) return helpString[3];
        if (oneSegment >= 240 && oneSegment <= 255) return helpString[4];
        return helpString[7]; //返回一个空字符串  不代表任何
    }

}


全部评论

相关推荐

评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务