世界上并没有完美的程序,但是我们并不因此而沮丧,因为写程序就是一个不断追求完美的过程。
题目描述
请解析IP地址和对应的掩码,进行分类识别。要求按照A/B/C/D/E类地址归类,不合法的地址和掩码单独归类。
所有的IP地址划分为 A,B,C,D,E五类
A类地址1.0.0.0~126.255.255.255;
B类地址128.0.0.0~191.255.255.255;
C类地址192.0.0.0~223.255.255.255;
D类地址224.0.0.0~239.255.255.255;
E类地址240.0.0.0~255.255.255.255
私网IP范围是:
10.0.0.0~10.255.255.255
172.16.0.0~172.31.255.255
192.168.0.0~192.168.255.255
子网掩码为二进制下前面是连续的1,然后全是0。(例如:255.255.255.32就是一个非法的掩码)
注意二进制下全是1或者全是0均为非法
注意:
1. 类似于【0.*.*.*】和【127.*.*.*】的IP地址不属于上述输入的任意一类,也不属于不合法ip地址,计数时可以忽略
2. 私有IP地址和A,B,C,D,E类地址是不冲突的
输入描述:
多行字符串。每行一个IP地址和掩码,用~隔开。
输出描述:
统计A、B、C、D、E、错误IP地址或错误掩码、私有IP的个数,之间以空格隔开。
示例1
输入
复制
10.70.44.68~255.254.255.0
1.0.0.1~255.0.0.0
192.168.0.2~255.255.255.0
19..0.~255.255.255.0
输出
复制
1 0 1 0 0 2 1
解决:
public class test {
private static String w3 = "((([.][2][0-5][0-5])|([.][1][0-9][0-9])|([.][1-9][0-9])|([.][0-9])){3})";
private static String w2 = "((([.][2][0-5][0-5])|([.][1][0-9][0-9])|([.][1-9][0-9])|([.][0-9])){2})";
private static String w1 = "((([.][2][0-5][0-5])|([.][1][0-9][0-9])|([.][1-9][0-9])|([.][1-9])))";
private static String w = "((([2][0-5][0-5])|([1][0-9][0-9])|([1-9][0-9])|([0-9])))";
private static String regA = "(([1][0-2][0-6])|([1-9][0-9])|([0-9]))" + w3;
private static String regB = "(([1][2][8-9])|([1][3-8][0-9])|([1][9][0-1]))" + w3;
private static String regC = "(([1][9][2-9])|([2][0-2][0-3]))" + w3;
private static String regD = "(([2][2][4-9])|([2][3][0-9]))" + w3;
private static String regE = "(([2][4][0-9])|([2][5][0-5]))" + w3;
private static String regS1 = "([1][0])"+w3;
private static String regS2 = "([1][7][2]).(([1][6-9])|([2][0-9])|([3][0-1]))"+w2;
private static String regS3 = "([1][9][2]).([1][6][8])"+w2;
private static String regY = "([2][5][5])(.[0]){3}|([2][5][5]).([2][5][5])(.[0]){2}|([2][5][5])([.][2][5][5]){2}.[0]";
private static String regN = "([2][5][5])([.][2][5][5]){3}|([0](.[0]){3})";
private static String reg0 = w + "([.][0]){3}";
private static String reg1 = "255" + w1 + "([.][0]){2}";
private static String reg2 = "255.255" + w1 + "([.][0])";
private static String reg3 = "255.255.255" + w1;
private static Pattern pattern0 = Pattern.compile(reg0);
private static Pattern pattern1 = Pattern.compile(reg1);
private static Pattern pattern2 = Pattern.compile(reg2);
private static Pattern pattern3 = Pattern.compile(reg3);
private static Pattern patternY = Pattern.compile(regY);
private static Pattern patternN = Pattern.compile(regN);
private static Pattern patternA = Pattern.compile(regA);
private static Pattern patternB = Pattern.compile(regB);
private static Pattern patternC = Pattern.compile(regC);
private static Pattern patternD = Pattern.compile(regD);
private static Pattern patternE = Pattern.compile(regE);
private static Pattern patternS1 = Pattern.compile(regS1);
private static Pattern patternS2 = Pattern.compile(regS2);
private static Pattern patternS3 = Pattern.compile(regS3);
private static boolean hasA (String ip) {
return patternA.matcher(ip).matches();
}
private static boolean hasB (String ip) {
return patternB.matcher(ip).matches();
}
private static boolean hasC (String ip) {
return patternC.matcher(ip).matches();
}
private static boolean hasD (String ip) {
return patternD.matcher(ip).matches();
}
private static boolean hasE (String ip) {
return patternE.matcher(ip).matches();
}
private static boolean hasS (String ip) {
boolean b1 = patternS1.matcher(ip).matches();
boolean b2 = patternS2.matcher(ip).matches();
boolean b3 = patternS3.matcher(ip).matches();
return b1 || b2 || b3;
}
private static boolean hasY (String ip) {
boolean bY = patternY.matcher(ip).matches();
boolean bN = patternN.matcher(ip).matches();
if (bY) {return true;}
if (bN) {return false;}
return pan(ip);
}
private static boolean pan (String ip) {
String[] ss = ip.split(".");
if (ss.length == 4) {
boolean b = pattern0.matcher(ip).matches();
if (b) {
return dan(ss[0]);
}
b = pattern1.matcher(ip).matches();
if (b) {
return dan(ss[1]);
}
b = pattern2.matcher(ip).matches();
if (b) {
return dan(ss[2]);
}
b = pattern3.matcher(ip).matches();
if (b) {
return dan(ss[3]);
}
}
return false;
}
private static boolean dan (String s) {
if (null != s && !"".equals(s)) {
int n = Integer.valueOf(s);
return has0end(to2(n));
}
return false;
}
private static String to2 (int n) {
if (n != 0) {
StringBuilder sb = new StringBuilder();
foo(n, sb);
sb.reverse();
return sb.toString();
}
return "";
}
private static void foo (int tmp, StringBuilder sb) {
while (true) {
if (tmp == 1) {
sb.append(1);
break;
} else {
sb.append(tmp%2);
tmp /= 2;
}
}
}
private static boolean has0end (String s) {
if (!"".equals(s)) {
char[] chars = s.toCharArray();
int len = chars.length;
for (int i=0; i<len; i++) {
if('1' == chars[i] && i!=0 && '0' == chars[i-1]) {
return false;
}
}
}
return true;
}
private static String getCount (String...ips) {
List<String> ls = Arrays.asList("A", "B", "C", "D", "E", "O", "S");
Map<String, Integer> map = new HashMap<>(16);
for(String str: ips) {
String[] ss = str.split("~");
String ip1 = ss[0];
String ip2 = ss[1];
if (!hasY(ip2)) {
mapCount("O", map);
continue;
}
boolean flag = true;
if (hasA(ip1)) {
mapCount("A", map);
flag = false;
} else if (hasB(ip1)) {
mapCount("B", map);
flag = false;
} else if (hasC(ip1)) {
mapCount("C", map);
flag = false;
} else if (hasD(ip1)) {
mapCount("D", map);
flag = false;
} else if (hasE(ip1)) {
mapCount("E", map);
flag = false;
}
if (hasS(ip1)) {
mapCount("S", map);
flag = false;
}
if (flag) {
mapCount("O", map);
}
}
StringBuilder sb = new StringBuilder();
ls.forEach(s -> {
Integer cnt = map.get(s);
sb.append(null == cnt?0:cnt).append(" ");
});
return sb.toString();
}
private static void mapCount (String key, Map<String, Integer> map) {
if (map.containsKey(key)) {
map.put(key, map.get(key)+1);
} else {
map.put(key, 1);
}
}
public static void main(String[] args) {
String[] ss = {"10.70.44.68~255.254.255.0",
"1.0.0.1~255.0.0.0",
"192.168.0.2~255.255.255.0",
"19..0.~255.255.255.0"};
String re = getCount(ss);
System.out.println(re);
}
}
得出结果:
1 0 1 0 0 2 1
题目有歧义,并没有说明要先判断子网掩码,如果是平等的,ABCDE类型与私有IP有重合的,既然说明了他们之间没有冲突,那么就会出现IP既属于ABCDE中的一种又属于私有的情况,亦或是给一个优先级,优先判断一种类型。