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

