题解 | #判断两个IP是否属于同一子网#

判断两个IP是否属于同一子网

https://www.nowcoder.com/practice/34a597ee15eb4fa2b956f4c595f03218

import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.lang.System;

public class Main{
    
    //不直接转换是因为可能不是数字
    private static Integer getOneNum(String s) {
        int num = 0;
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (!(c >= '0' && c <= '9')) {
                return null;
            }
            int cNum = c - '0';
            num = num * 10 + cNum;
        }
        //超过范围也返回null
        if (!(num >= 0 && num <= 255)) {
            return null;
        }
        return num;
    }

    //ip对应的十进制数,这里只判断范围,不判断子网掩码的连续。如果非法则返回null
    //要用long,否则可能会越界
    private static Long getNum(String s) {
        if (s == null) {
            return null;
        }
        String[] sArray = s.split("\\.");
        if (sArray.length != 4) {
            return null;
        }

        long num = 0;
        //乘数。把整数转为二进制表示时,用取余和整除的方式做。
        //新取余的那一位要乘以这个乘数,而后乘数更新为原来的2倍,相当于2^n
        int m = 1;
        //从后往前处理
        for (int i = 3; i >= 0; i--) {
            Integer tempNum = getOneNum(sArray[i]);
            //null代表不是数字
            if (tempNum == null) {
                return null;
            }
            for (int j = 0; j < 8; j++) {
                int temp = tempNum % 2;
                num = temp * m + num;

                tempNum = tempNum / 2;
                m = m * 2;
            }
        }
        return num;
    }

    //子网掩码对应的十进制数,流程和上面ip的十进制数一样,不过多了对连续性的判断
    private static Long getSubnetMask(String s) {
        if (s == null) {
            return null;
        }
        String[] sArray = s.split("\\.");
        if (sArray.length != 4) {
            return null;
        }

        //子网掩码的字符数组
        char[] cs = new char[32];
        int k = 31;
        long num = 0;
        //乘数。把整数转为二进制表示时,用取余和整除的方式做。
        //新取余的那一位要乘以这个乘数,而后乘数更新为原来的2倍,相当于2^n
        int m = 1;
        //从后往前处理
        for (int i = 3; i >= 0; i--) {
            Integer tempNum = getOneNum(sArray[i]);
            //null代表不是数字
            if (tempNum == null) {
                return null;
            }
            for (int j = 0; j < 8; j++) {
                int temp = tempNum % 2;
                num = temp * m + num;
                //字符加入子网掩码
                cs[k] = temp == 0 ? '0' : '1';
                k--;

                tempNum = tempNum / 2;
                m = m * 2;
            }
        }

        //判断连续性,第一位如果不为'1'就直接返回null。
        // 循环判断是否为1,为1则计数,不为1则跳出。然后循环判断是否为0,为0则计数,不为0则跳出。最后如果计数不为32则说明错误
        int i = 0;
        while (i < 32 && cs[i] == '1') {
            i++;
        }
        while (i < 32 && cs[i] == '0') {
            i++;
        }
        if (i != 32) {
            return null;
        }

        return num;
    }

    private static int getResult(String[] ss) {
        Long subnetMask = getSubnetMask(ss[0]);
        Long ip1 = getNum(ss[1]);
        Long ip2 = getNum(ss[2]);
        //返回null代表非法
        if (subnetMask == null || ip1 == null || ip2 == null) {
            return 1;
        }
        long result1 = subnetMask & ip1;
        long result2 = subnetMask & ip2;
        return result1 == result2 ? 0 : 2;
    }
    
    
    public static void main(String[] args) throws IOException{
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        String[] ss = new String[3];
        while ((ss[0] = bf.readLine()) != null) {
            ss[1] = bf.readLine();
            ss[2] = bf.readLine();
            System.out.println(getResult(ss));
        }
//         ss[0] = bf.readLine();
//         ss[1] = bf.readLine();
//         ss[2] = bf.readLine();
//         System.out.println(getResult(ss));
    }
}

#华为机试#
全部评论

相关推荐

12-19 22:04
武汉大学 Java
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务