题解 | #识别有效的IP地址和掩码并进行分类统计#
识别有效的IP地址和掩码并进行分类统计
http://www.nowcoder.com/practice/de538edd6f7e4bc3a5689723a7435682
思路
- 首先,对
ip
和mask
进行合法性判断ip[0] == 0 || ip[0] == 127
不用管ip
和mask
中某个位置 “为空”,则不合法(对应isValid
返回结果为null
)- 掩码合法性判断
isMask
:如果 “最低位 1” 在 “最高位 0” 左边相邻位置,则当前 mask 合法;否则,不合法注意:初始化包含了 mask 全是 0、或全是 1 的处理
int topZero = 9;
int minOne = -1;
- 然后,判断
ip
是否为 “私有地址”,见isPrivate
方法; - 判断
ip
是否为 A、B、C、D 类地址
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int sumA = 0;
int sumB = 0;
int sumC = 0;
int sumD = 0;
int sumE = 0;
int sumError = 0;
int sumPrivate = 0;
while (in.hasNextLine()) {
String line = in.nextLine();
String[] arr = line.split("~");
int[] ip = isValid(arr[0]);
int[] mask = isValid(arr[1]);
// 合法性判断
if (ip != null && (ip[0] == 0 || ip[0] == 127)) {
continue;
}
if (ip == null || mask == null || !isMask(mask)) {
sumError++;
continue;
}
// 私有地址
if (isPrivate(ip)) {
sumPrivate++;
// continue; // 私有IP地址和A,B,C,D,E类地址是不冲突的
}
// A类地址
if (ip[0] >= 1 && ip[0] <= 126) {
sumA++;
continue;
}
// B类地址
if (ip[0] >= 128 && ip[0] <= 191) {
sumB++;
continue;
}
// C类地址
if (ip[0] >= 192 && ip[0] <= 223) {
sumC++;
continue;
}
// D类地址
if (ip[0] >= 224 && ip[0] <= 239) {
sumD++;
continue;
}
// E类地址
if (ip[0] >= 240 && ip[0] <= 255) {
sumE++;
continue;
}
}
System.out.println(sumA + " " + sumB + " " + sumC + " " + sumD + " " + sumE + " " + sumError + " " + sumPrivate);
in.close();
}
// 判断是否合法(即,判断每个 s[i] 是否都是数字)
static int[] isValid(String s) {
String[] arr = s.split("\\.");
int[] res = new int[4];
for (int i = 0; i < arr.length; i++) {
if ("".equals(arr[i])) {
return null;
}
res[i] = Integer.parseInt(arr[i]);
}
return res;
}
// mask 已经过非空判断
static boolean isMask(int[] mask) {
// 初始化包含了 mask 全是0、或全是1的处理
int topZero = 9;
int minOne = -1;
int index = 0; // 低位 --> 高位(即,0 --> 31)
for (int j = mask.length - 1; j >= 0; j--) {
int cnt = mask[j];
for (int i = 0; i < 8; i++) {
int d = (cnt & 1);
// 找 “最低位 1” 的位置
if (minOne == -1 && d == 1) {
minOne = index;
}
// 找 “最高位 0” 的位置
if (d == 0) {
topZero = index;
}
index++;
cnt >>>= 1;
}
}
return (topZero + 1) != minOne;
}
// ip 已经过合法性判断
static boolean isPrivate(int[] ip) {
if (ip[0] == 10) {
return true;
}
if (ip[0] == 172 && (ip[1] >= 16 && ip[1] <= 31)) {
return true;
}
if (ip[0] == 192 && ip[1] == 168) {
return true;
}
return false;
}
}
注意
ip[0] == 0 || ip[0] == 127)
不计数,一定要先于其他合法性判断;- 私有IP地址和 A,B,C,D,E 类地址是不冲突的,所以不能
continue
; isMask
初始化包含了 mask 全是 0、或全是 1 的处理
前两次,卡在如下案例了:
42.53.252.112~255.0.0.0
166.237.7.68~255.0.0.0
136.3.73.64~255.255.0.0
204.29.136.133~255.255.0.245
195.30.208.94~255.255.0.213
154.253.86.183~255.200.255.0
94.164.187.131~255.255.0.0
167.79.164.186~255.0.0.0
194.172.2.64~255.255.0.0
210.212.79.137~255.255.255.42
143.151.137.40~255.255.255.255
184.145.79.157~255.0.0.0
100.214.131.51~255.255.255.255
233.10.182.98~255.0.0.125
99.184.165.228~255.0.0.82
92.20.159.86~255.0.0.0
198.198.174.83~255.0.0.0
17.158.122.89~255.255.75.255
149.253.103.237~255.0.26.0
91.243.182.7~255.0.0.0
36.76.55.4~255.255.255.255
126.54.86.143~255.0.0.0
错误原因:isMask
中初始化 、,没有考虑 mask
全是 0、或全是 1 的情况 \捂脸\