题解 | #识别有效的IP地址和掩码并进行分类统计#
识别有效的IP地址和掩码并进行分类统计
https://www.nowcoder.com/practice/de538edd6f7e4bc3a5689723a7435682
讲一下做这题遇到的几个坑,真是差点把我给搞吐了:
- 类似于【0.*.*.*】和【127.*.*.*】的IP地址不属于上述输入的任意一类,也不属于不合法ip地址,计数时请忽略,也就是说ip是0或者127开头的直接跳过,即使子网掩码是非法的,也不计入错误ip地址里,对ip首位是否为0或127的判断要放在最前面;
- 用“.”作为分割符对字符串进行分割时,忘记了要进行转义:s[0].split("\\."),不能直接用s[0].split("\\.");
- 进行错误子网掩码判断时,要求满足连续且个数不为零的1加上连续且个数不为零的1,1和1中间不能存在0,将其转换成二进制要补齐8位,防止出现【255.0.1.0】、【255.15.0.0】等漏判情况;
- 进行错误ip地址判断时,开始用的是“s[0].contains("..") || s[0].contains("...")”,然后部分案例结果始终不对,漏判了【123.123.123.】或【.123.123.】这种首尾段落缺失的情况,然后改成ip地址的段数不为4进行判断:a.length != 4;
- 本来想试试用正则表达式来进行判断,捣鼓了两下发现自己学艺不精,太难了遂放弃了。
import java.util.*; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int N1 = 0, N2 = 0, N3 = 0, N4 = 0, N5 = 0, N6 = 0, N7 = 0; while (sc.hasNextLine()) { String[] s = sc.nextLine().trim().split("~"); String[] a = s[0].split("\\."); //将子网掩码部分转换成二进制字符串 String[] b = s[1].split("\\."); StringBuilder sb = new StringBuilder(); for (int i = 0; i < b.length; ++i) { String temp = Integer.toBinaryString(Integer.parseInt(b[i])); //不足8位需在前面补0,防止漏判255.0.1.0等情形 while (temp.length() < 8) { temp = "0" + temp; } sb.append(temp); } String sm = sb.toString(); if ("0".equals(a[0]) || "127".equals(a[0])) { continue; } if (a.length != 4 || b.length != 4 || !isSubnetMask(sm)) { N6++ ; continue; } int a0 = Integer.parseInt(a[0]); int a1 = Integer.parseInt(a[1]); int a2 = Integer.parseInt(a[2]); int a3 = Integer.parseInt(a[3]); if (a1 >= 0 && a1 <= 255 && a2 >= 0 && a2 <= 255 && a3 >= 0 && a3 <= 255) { if (a0 >= 1 && a0 <= 126 ) { N1++; } else if (a0 >= 128 && a0 <= 191 ) { N2++; } else if (a0 >= 192 && a0 <= 223 ) { N3++; } else if (a0 >= 224 && a0 <= 239 ) { N4++; } else if (a0 >= 240 && a0 <= 255 ) { N5++; } } if (((a0 == 10 && a1 >= 0 && a1 <= 255) || (a0 == 172 && a1 >= 16 && a1 <= 31) || (a0 == 192 && a1 == 168)) && a2 >= 0 && a2 <= 255 && a3 >= 0 && a3 <= 255) { N7++; } } System.out.print(N1 + " " + N2 + " " + N3 + " " + N4 + " " + N5 + " " + N6 + " " + N7); } //判断是否为合法的二进制子网掩码 public static boolean isSubnetMask(String s) { int i1 = s.lastIndexOf("1"); int i2 = s.indexOf("0"); if (i1 != -1 && i2 != -1 && i2 - i1 == 1) { return true; } return false; } }