请解析IP地址和对应的掩码,进行分类识别。要求按照A/B/C/D/E类地址归类,不合法的地址和掩码单独归类。

世界上并没有完美的程序,但是我们并不因此而沮丧,因为写程序就是一个不断追求完美的过程。

题目描述
请解析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中的一种又属于私有的情况,亦或是给一个优先级,优先判断一种类型。

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

这是谁的博客?

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值