题解 | #识别有效的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); } } }