话不多说,上代码 1.首先通过字符串切割拿到ip和markCode 2.再对ip进行一步初级过滤,保证ip的合法性,让我下面处理时只用关心ip的分类,最后将ip和markcode放入Map中 3.循环Map,对markCode和ip做处理 3.1优先对markCode做校验(这里耽误了好久。。。)之前认为最简单的地方,实际是最麻烦的。 3.2对ip进行处理,因为前面保证了ip的合法性,这里只需要无脑比较即可(不要喷我),大家有更好的办法请打在公屏上。
总的来说这一题不难,就是逻辑优点多。
import java.util.*;
public class Main {
static int A;
static int B;
static int C;
static int D;
static int E;
static int Fail;
static int PIP;
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
// 11111111 = 255
List<String> ipMarks = new ArrayList<>();
while (s.hasNextLine()){
String Line = s.nextLine();
if (Line.equals("")) break;
ipMarks.add(Line);
}
Map<String,String> ipAMarkC = new HashMap<>();
for (String ipMark : ipMarks) {
String[] split = ipMark.split("~");
String ip = split[0];
String[] num = ip.split("\\.");
String first = num[0];
if (null != first && !"".equals(first) && !"0".equals(first) && !"127".equals(first)) {
if (Arrays.asList(num).contains("")){
Fail += 1;
}else {
// 保证ip都是合法的
ipAMarkC.put(ip, split[1]);
}
}
}
// System.out.println(ipAMarkC);
ipAMarkC.forEach(
(ip, markCode) ->{
// 如果掩码校验失败,不校验ip
if (markCodeValidate(markCode)){
ipHandler(ip);
}
}
);
System.out.println(A+" "+B+" "+C+" "+D+" "+E+" "+Fail+" "+PIP);
}
// 校验子网掩码这里最麻烦
private static boolean markCodeValidate(String markCode) {
String[] codes = markCode.split("\\.");
String zero = "00000000"; // 补齐8位二进制
StringBuilder result = new StringBuilder();
// 这里我用两个count来区分全为0和全为1,大家想想有没有更好的办法
int zeroCount = 0;
int twoCount = 0;
for (String code : codes) {
if (code.equals("0")) {
zeroCount++;
}
if (code.equals("255")){
twoCount++;
}
String bin = Integer.toBinaryString(Integer.parseInt(code));
result.append(zero.substring(0,8-bin.length()) + bin); //字符串拼接捏
}
if (zeroCount == 4 || twoCount == 4){
Fail += 1;
return false;
}
// 这里我通过切割判断数组长度,因为子网掩码一定的1和0左右分开的
String[] split = result.toString().split("[0]");
if (split.length <= 1){
return true;
}
Fail += 1;
return false;
}
private static void ipHandler(String ip) {
// 先截取第一个地址处理 abcde类地址
// 再判断是否是私网ip
String[] codes = ip.split("\\.");
Integer firstCode = Integer.valueOf(codes[0]);// 为地址分类
Integer secondCode = Integer.valueOf(codes[1]);// 为地址分类
boolean canIsPrivate = false;
if (firstCode >= 1 && firstCode <= 126){
A += 1;
canIsPrivate = true;
}
if (firstCode >= 128 && firstCode <= 191){
B += 1;
canIsPrivate = true;
}
if (firstCode >= 192 && firstCode <= 223){
C += 1;
canIsPrivate = true;
}
if (firstCode >= 224 && firstCode <= 239) D += 1;
if (firstCode >= 240 && firstCode <= 255) E += 1;
if (canIsPrivate){
// 检查是否为私网地址
if (firstCode.equals(10)
|| (firstCode.equals(172) && (secondCode >= 16 && secondCode <= 31))
|| (firstCode.equals(192) && secondCode.equals(168))){
PIP += 1;
}
}
}
}