题解 | #识别有效的IP地址和掩码并进行分类统计#
识别有效的IP地址和掩码并进行分类统计
http://www.nowcoder.com/practice/de538edd6f7e4bc3a5689723a7435682
注释比较全,看注释就行
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 记录所有的错误数
int[] count = new int[7];
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextLine()) { // 注意 while 处理多个 case
String[] s = in.nextLine().split("~");
String[] ips = s[0].split("\\.");
// 类似于【0.*.*.*】和【127.*.*.*】的IP地址不属于上述输入的任意一类
if ("0".equals(ips[0]) || "127".equals(ips[0])) {
continue;
}
if (dnsIsOk(s[1]) && ipIsOK(s[0])) {
// 开始判断
int ip1 = Integer.parseInt(ips[0]);
int ip2 = Integer.parseInt(ips[1]);
if (ip1 >= 1 && ip1 <= 126) {
count[0]++;
} else if (ip1 >= 128 && ip1 <= 191) {
count[1]++;
} else if (ip1 >= 192 && ip1 <= 223) {
count[2]++;
} else if (ip1 >= 224 && ip1 <= 239) {
count[3]++;
} else if (ip1 >= 240 && ip1 <= 255) {
count[4]++;
}
// 私有IP地址和A,B,C,D,E类地址是不冲突的 这里不能接上面的 else if
if (ip1 == 10) {
count[6]++;
}
if (ip1 == 172 && ip2 >= 16 && ip2 <= 31) {
count[6]++;
}
if (ip1 == 192 && ip2 == 168) {
count[6]++;
}
} else {
// 错误子网掩码或 IP
count[5]++;
}
}
System.out.println(count[0] + " " + count[1] + " " + count[2] + " " + count[3] + " " + count[4] + " " + count[5] + " " + count[6]);
}
// 是否是合法 IP
public static boolean ipIsOK(String s) {
boolean flag = true;
String[] ips = s.split("\\.");
if (ips.length == 4) {
for (int i = 0; i < 4; i++) {
String ss = ips[i].trim();
if (ss.isEmpty()) {
flag = false;
break;
}
int j = Integer.parseInt(ss);
if (ss.length() > 3) {
flag = false;
break;
} else if (!"0".equals(ss) && ss.charAt(0) == '0') {
flag = false;
break;
} else if (j < 0 || j > 255) {
flag = false;
break;
}
}
} else {
flag = false;
}
return flag;
}
// 判断子网掩码是否合法
// 将子网掩码转换为 32 为二进制,看第一个 0 的索引和最后一个 1 的索引是否的大小关系
public static boolean dnsIsOk(String s) {
boolean flag = true;
String[] dns = s.split("\\.");
if (dns.length == 4) {
for (int i = 0; i < 4; i++) {
String ss = dns[i].trim();
if (ss.length() == 0) {
flag = false;
break;
}
int j = Integer.parseInt(ss);
if (ss.length() > 3) {
flag = false;
break;
} else if (j < 0 || j > 255) {
flag = false;
break;
}
}
} else {
flag = false;
}
// 只有 flag 为 true,才表名 掩码没有格式上的问题,这时候再判断是否是1在前0在后
if (flag) {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < dns.length; i++) {
String ss = Integer.toString(Integer.valueOf(dns[i]), 2);
ss = "00000000" + ss;
builder.append(ss.substring(ss.length() - 8));
}
String ret = builder.toString();
//最后一个1在第一个0之前,有效,否则无效(注意二进制下全是1或者全是0均为非法子网掩码)这里全 1 或全 0 也是 false
flag = ret.indexOf("0") > ret.lastIndexOf("1");
}
return flag;
}
}
