华为Oj--识别有效的IP地址和掩码并进行分类统计

华为机试题

识别有效的IP地址和掩码并进行分类统计

题目描述

题目描述

请解析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就是一个非法的掩码)
本题暂时默认以0开头的IP地址是合法的,比如0.1.1.2,是合法地址

输入描述:
多行字符串。每行一个IP地址和掩码,用~隔开。

输出描述:
统计A、B、C、D、E、错误IP地址或错误掩码、私有IP的个数,之间以空格隔开。

输入例子:
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

接下来提出的坑,都是自己踩过的,编程会用到。

  • 私网IP地址也是A,B,C,D,E类地址
  • 如果掩码错误了,那么就不判断ip地址为哪一类了
  • 将ip地址字符串转换为01序列字符串时需要补0
具体就是如32Integer.parseInt(string),以后获得的String100000,而我们想要的应该是00100000这样的字符串

   其他的有问题看注释就行,另外输入输出实在是一门很“高深”的学问,难了我好久,错误提交好多次。还是喜欢leetcode

Code

import java.util.Scanner;

/**
 * Created by loveqh on 2016/10/12.
 */
public class DetectIpAndMask {


    //    A、B、C、D、E、错误IP地址或错误掩码、私有IP的个数

    /**
     * 返回
     * 0:A
     * 1:B
     * 2:C
     * 3:D
     * 4:E
     *
     * @param str
     * @return
     */
    public static int classRifyIp(String str) {
        String[] ips = str.split("\\.");
        int[] ipInts = strings2Num(ips);
        int ipFirst = ipInts[0];
        if (ipFirst >= 1 && ipFirst <= 126)
            return 0;
        if (ipFirst >= 128 && ipFirst <= 191)
            return 1;
        if (ipFirst >= 192 && ipFirst <= 223)
            return 2;
        if (ipFirst >= 224 && ipFirst <= 239)
            return 3;
        if (ipFirst >= 240 && ipFirst <= 255)
            return 4;
        return Integer.MAX_VALUE;
    }

    /**
     * 如果为5则表示错误,否则就有效的掩码
     *
     * @param str
     * @return
     */
    public static int classRifyMask(String str) {
        if (!isValidMask(str)) {
            return 5;
        }
        return Integer.MAX_VALUE;
    }

    /**
     * 如果是6则表示是私有IP地址
     *
     * @param str
     * @return
     */
    public static int classRifyPrivate(String str) {
        if (isPrivateIp(str))
            return 6;
        return Integer.MAX_VALUE;
    }

    /**
     * 判断字符串是够是有效的子网掩码
     *
     * @param string
     * @return
     */
    private static boolean isValidMask(String string) {
        String str = num2BinaryString(string);
        int lastOneIndex = str.lastIndexOf("1");
        if (lastOneIndex == str.length() - 1) return false;
        if (lastOneIndex > 0) {
            char[] rest = str.substring(0, lastOneIndex).toCharArray();
            for (int i = 0; i < rest.length; i++) {
                if (rest[i] == '0') {
                    return false;
                }
            }
        }
        return true;
    }

    /**
     * 判断字符串是否私有IP地址
     *
     * @param str
     * @return
     */
    private static boolean isPrivateIp(String str) {
        String[] ips = str.split("\\.");
        int[] ipInts = strings2Num(ips);
        int ipFirst = ipInts[0];
        int ipSecond = ipInts[1];
        if (ipFirst == 10)
            return true;
        if (ipFirst == 172 && ipSecond >= 16 && ipSecond <= 31)
            return true;
        if (ipFirst == 192 && ipSecond == 168)
            return true;
        return false;
    }

    /**
     * 是否为有效的ip地址
     *
     * @param str
     * @return
     */
    private static boolean isValidIp(String str) {
        String[] strings = str.split("\\.");
        for (String string : strings) {
            if ("".equals(string)) {
                return false;
            }
            Integer integer = Integer.parseInt(string);
            if (integer < 0 || integer > 255) {
                return false;
            }
        }
        return true;
    }

    /**
     * 将ip地址字符串转换为01序列字符串。
     *
     * @param str
     * @return
     */
    private static String num2BinaryString(String str) {
        String[] strings = str.split("\\.");
        StringBuffer sb = new StringBuffer();
        for (String string : strings) {
            String temp = Integer.toBinaryString(Integer.parseInt(string.trim()));
            int i = 8 - temp.length();
            for (int k = 0; k < i; k++) {
                sb.append('0');
            }
            sb.append(temp);
        }
        return sb.toString();
    }

    /**
     * ip字符数组转换为数字数组
     *
     * @param ips
     * @return
     */
    private static int[] strings2Num(String[] ips) {
        int[] res = new int[ips.length];
        int i = 0;
        for (String str : ips) {
            res[i] = Integer.parseInt(str);
            i++;
        }
        return res;
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int[] res = new int[7];
        String ipMask = null;
        while (sc.hasNext()) {
            ipMask = sc.nextLine();
            String[] ipMasks = ipMask.split("~");
            String ip = ipMasks[0];
            String mask = ipMasks[1];
            int maskInt = DetectIpAndMask.classRifyMask(mask);
            if (maskInt == Integer.MAX_VALUE) {
                if (isValidIp(ip)) {
                    int ipInt = DetectIpAndMask.classRifyIp(ip);
                    if (ipInt != Integer.MAX_VALUE) {
                        res[ipInt]++;
                    }
                    int privateInt = DetectIpAndMask.classRifyPrivate(ip);
                    //私有IP地址
                    if (privateInt != Integer.MAX_VALUE) {
                        res[privateInt]++;
                    }
                } else {
                    res[5]++;
                }
            } else {
                res[maskInt]++;
            }
        }
        System.out.println(res[0] + " " + res[1] + " " + res[2] + " " + res[3] + " " + res[4] + " " + res[5] + " " + res[6]);
    }

}


你可能感兴趣的:(leetcode,huaweicode)