题解 | #识别有效的IP地址和掩码并进行分类统计#
识别有效的IP地址和掩码并进行分类统计
https://www.nowcoder.com/practice/de538edd6f7e4bc3a5689723a7435682
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
Map<String, Integer> sortCountMap = new LinkedHashMap<>();
sortCountMap.put("A", 0);
sortCountMap.put("B", 0);
sortCountMap.put("C", 0);
sortCountMap.put("D", 0);
sortCountMap.put("E", 0);
sortCountMap.put("wrongInput", 0);
sortCountMap.put("privateIp", 0);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNext()) { // 注意 while 处理多个 case
String str = in.next();
//拆分ip和子网掩码
String[] fac = str.split("~");
//Ip
String ip = fac[0];
//掩码
String cover = fac[1];
//判断ip是否合法
if (!ipCheck(ip)) {
sortCountMap.put("wrongInput", sortCountMap.get("wrongInput") + 1);
}
String ipHead = ip.split("\\.")[0];
String sec = ip.split("\\.")[1];
//判断掩码是否合法:不全为255且只有255和0且0在最后
if (!coverCheck(cover, ipHead)) {
sortCountMap.put("wrongInput", sortCountMap.get("wrongInput") + 1);
}
//ip种类和私有地址:ip和掩码格式都正确才能进行统计
if (coverCheck(cover, ipHead) && ipCheck(ip)) {
int second = Integer.parseInt(sec);
int head = Integer.parseInt(ipHead);
if (head >= 1 && head <= 126) {
sortCountMap.put("A", sortCountMap.get("A") + 1);
if (head == 10) {
sortCountMap.put("privateIp", sortCountMap.get("privateIp") + 1);
}
}
if (head >= 128 && head <= 191) {
sortCountMap.put("B", sortCountMap.get("B") + 1);
if (head == 172 && second >= 16 && second <= 32) {
sortCountMap.put("privateIp", sortCountMap.get("privateIp") + 1);
}
}
if (head >= 192 && head <= 223) {
sortCountMap.put("C", sortCountMap.get("C") + 1);
if (head == 192 && second == 168) {
sortCountMap.put("privateIp", sortCountMap.get("privateIp") + 1);
}
}
if (head >= 224 && head <= 239) {
sortCountMap.put("D", sortCountMap.get("D") + 1);
}
if (head >= 240 && head <= 255) {
sortCountMap.put("E", sortCountMap.get("E") + 1);
}
}
}
Set<String> set = sortCountMap.keySet();
for (String kind : set) {
System.out.print(sortCountMap.get(kind) + " ");
}
}
public static boolean ipCheck(String ip) {
//长度检查
String[] ipComs = ip.split("\\.");
if (ipComs.length != 4) {
return false;
}
for (int i = 0; i < ipComs.length; i++) {
String coms = ipComs[i];
//某部分为空
if (coms.length() == 0) {
return false;
} else if (Integer.parseInt(coms) < 0 || Integer.parseInt(coms) > 255) {
//某部分值不在0-255
return false;
}
}
return true;
}
public static boolean coverCheck(String cover, String ipHead) {
//长度检查
String[] coverComs = cover.split("\\.");
if (coverComs.length != 4) {
return false;
}
//全255,全0
if (cover.equals("255.255.255.255") || cover.equals("0.0.0.0")) {
return false;
}
//1在前,0在后
int[] check=new int[4];
for (int i = 0; i < coverComs.length; i++) {
String coverCom = coverComs[i];
//特殊ip不予统计
if (!(ipHead.equals("127") || ipHead.equals("0"))) {
//递减序列
if (coverCom.length() == 0) {
return false;
} else if (!(coverCom.equals("0") || coverCom.equals("128") ||
coverCom.equals("192") || coverCom.equals("224")
|| coverCom.equals("240") ||coverCom.equals("248") ||
coverCom.equals("252") || coverCom.equals("254")
|| coverCom.equals("255"))) {//非:0 128 192 224 240 252 254 255
return false;
} else {
//是合法数值
int num=Integer.parseInt(coverCom);
check[i]=num;
}
}
}
//合法掩码是非递增序列
for(int i=0;i<4;i++){
int max=check[i];
for(int j=i+1;j<4;j++){
if(check[j]>max){
return false;
}
}
}
return true;
}
}
分步的重要性:
1.检查ip(长度为4,数值0-255)
2.检查掩码(长度为4,忽略0和127,数值0-255,1全在前面或者十进制值非递增)
3.统计种类和私有地址数(因为有重合所以放一起统计)
4.按序打印
整整两个小时啊。。。



