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

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

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

import java.util.*;

public class Main {
    private static HashMap<String, Integer> category;

    public static void main(String[] args) {

        ArrayList<String> IPs = new ArrayList<>();
        ArrayList<String> masks = new ArrayList<>();

        Scanner in = new Scanner(System.in);
        while (in.hasNext()) {
            String buffer = in.nextLine();
            IPs.add(buffer.split("~")[0]);
            masks.add(buffer.split("~")[1]);
        }

        for (String ip : IPs) {
            if (isIpFormatOK(ip)) {
                Kit.classifyIp(ip, category);
            } else {
                category.put("Error", category.get("Error") + 1);
            }
        }

        for (String mask : masks) {
            if (!isMaskFormatOK(mask) || !Kit.isMaskValid(mask)) {
                category.put("Error", category.get("Error") + 1);
            }
        }

        for (String key : category.keySet()) {
            System.out.print(category.get(key) + " ");
        }
    }

    public static void initMap() {
        category = new HashMap<>();
        category.put("A", 0);
        category.put("B", 0);
        category.put("C", 0);
        category.put("D", 0);
        category.put("E", 0);
        category.put("Error", 0);
        category.put("Private", 0);
    }

    public static boolean isIpFormatOK(String ip) {
        String[] parts = ip.split("\\.");
        // 检查长度是否为4段
        if (!Kit.isLengthOK(parts)) {
            return false;
        }
        // 检查数值格式是否正确(0~255)
        if (!Kit.isFormatOK(parts)) {
            return false;
        }
        // 检查开头是否为0,0为非法IP地址开头
        if (parts[0].equals("0")) {
            return false;
        }
        return true;
    }

    public static boolean isMaskFormatOK(String mask) {
        // 枚举mask中会出现的数字
        String[] possible = {"255", "254", "252", "248", "240", "224", "192", "128", "0"};
        String[] parts = mask.split("\\.");
        // 检查长度是否为4段
        if (!Kit.isLengthOK(parts)) {
            return false;
        }
        // 检查数值格式是否正确
        if (!Kit.isFormatOK(parts)) {
            return false;
        }
        // 检查mask中的数值有无问题

        return true;
    }
}

class Kit {
    /**
     * 检查IP地址或者子网掩码的长度有无问题
     */
    static boolean isLengthOK(String[] parts) {
        return parts.length == 4;
    }

    /**
     * 检查IP地址或者子网掩码的数值有无问题(不判断是否合理)
     */
    static boolean isFormatOK(String[] parts) {
        char[] chars;
        int num;
        for (String part : parts) {
            // 检查是否为空
            if (part.isEmpty()) {
                return false;
            }
            // 检查是否为全部数字
            chars = part.toCharArray();
            for (char c : chars) {
                if (!Character.isDigit(c)) {
                    return false;
                }
            }
            // 检查是否在0-255
            num = Integer.parseInt(part);
            if (num < 0 || num > 255) {
                return false;
            }
        }
        return true;
    }

    public static boolean isMaskValid(String mask) {
        // 枚举mask中除了255之外,会出现的数字
        String[] all = {"255", "254", "252", "248", "240", "224", "192", "128", "0"};
        ArrayList<String> possible = new ArrayList<>(Arrays.asList(all));

        String[] parts = mask.split("\\.");

        boolean flag = true;
        // 一开始设置成合理的255
        String pre = "255";

        for (String part : parts) {
            // 若当前的数不存在于可能性当中
            if (!possible.contains(part)) {
                flag = false;
                break;
            }
            // 或者前面一个数已经不是255,当前数也还不是0
            if (!pre.equals("255") && !part.equals("0")) {
                flag = false;
                break;
            }
            pre = part;
        }
        return flag;
    }

    /**
     * 根据传进来的ip地址头1位即可判断从属
     */
    public static void classifyIp(String ip, HashMap<String, Integer> category) {
        int head = Integer.parseInt(ip.split("\\.")[0]);
        int second = Integer.parseInt(ip.split("\\.")[1]);

        // A类地址从1.0.0.0到126.255.255.255
        if (head < 127) {
            if (head == 10) { // 私网从10.0.0.0到10.255.255.255
                category.put("Private", category.get("Private") + 1);
            }
            category.put("A", category.get("A") + 1);
        } else if (head == 127) { // 127.*.*.* 的IP地址不属于上述输入的任意一类
            category.put("Error", category.get("Error") + 1);
        } else if (head < 192) { // B类地址从128.0.0.0到191.255.255.255
            if (head == 172 && second >= 16 && second < 32) { // 私网从172.16.0.0到172.31.255.255
                category.put("Private", category.get("Private") + 1);
            }
            category.put("B", category.get("B") + 1);
        } else if (head < 224) { // C类地址从192.0.0.0到223.255.255.255
            if (head == 192 && second == 168) { // 私网从192.168.0.0到192.168.255.255
                category.put("Private", category.get("Private") + 1);
            }
            category.put("C", category.get("C") + 1);
        } else if (head < 240) { // D类地址从224.0.0.0到239.255.255.255
            category.put("D", category.get("D") + 1);
        } else { // E类地址从240.0.0.0到255.255.255.255
            category.put("E", category.get("E") + 1);
        }
    }
}

全部评论

相关推荐

点赞 评论 收藏
分享
喜欢走神的孤勇者练习时长两年半:池是池,发是发,我曾池,我现黑
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务