题解 | #判断两个IP是否属于同一子网# 【模拟&位运算】

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

思路

  • 将输入数据转化为 32位二进制,即 input2binary,分别对应为 maskip1ip2
  • 有效性判断:若 maskip1ip2 中存在某一段不在 之间、或 mask 不满足子网掩码的规则,则直接返回
    • 子网掩码判断 isValidMask:从右向左遍历,若最高位 和 最低位 不相邻,则说明当前 mask 不合法
      • 此时,三者均已合法,需要判断 ip1ip2 是否在同一个子网中
    • 首先,将 32为二进制 ip1ip2mask 转化为十进制,分别对应为 intIp1intIp2intMask
    • 然后,判断 (intMask & intIp1) == (intMask & intIp2) 是否相等
      • 若相等,则说明在同一个子网中;否则,在属于不同网络
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNextLine()) {
            String line1 = in.nextLine();
            String line2 = in.nextLine();
            String line3 = in.nextLine();
            String mask = input2binary(line1);
            String ip1 = input2binary(line2);
            String ip2 = input2binary(line3);
            // 有效性判断
            if ("1".equals(ip1) || "1".equals(ip2) || "1".equals(mask) || !isValidMask(mask)) {
                System.out.println("1");
                continue;
            }
            int intMask = binary2ten(mask);
            int intIp1 = binary2ten(ip1);
            int intIp2 = binary2ten(ip2);
            boolean isSameNet = (intMask & intIp1) == (intMask & intIp2);
            System.out.println(isSameNet ? 0 : 2);
        }
        in.close();
    }

    // 输入串转化为32位二进制
    static String input2binary(String line) {
        String[] arr = line.split("\\.");
        StringBuilder res = new StringBuilder();
        for (String cnt : arr) {
            int n = Integer.parseInt(cnt);
            if (!isValid(n)) {
                return "1";
            }
            res.append(ten2binary(n));
        }
        return res.toString();
    }

    // 十进制转化为8位二进制
    static String ten2binary(int n) {
        StringBuilder s = new StringBuilder();
        for (int i = 0; i < 8; i++) {
            s.append(n & 1);
            n >>>= 1;
        }
        return s.reverse().toString();
    }

    // 32为二进制转化为十进制
    static int binary2ten(String s) {
        int res = 0;
        int power = 1;
        for (int i = s.length() - 1; i >= 0; i--) {
            int cnt = s.charAt(i) - '0';
            res += power * cnt;
            power <<= 1;
        }
        return res;
    }

    // 判断32二进制mask是否为子网掩码
    static boolean isValidMask(String mask) {
        int maxZeroIndex = -1;
        int minOneIndex = -1;
        for (int i = 31; i >= 0; i--) {
            if (minOneIndex == -1 && mask.charAt(i) == '1') {
                minOneIndex = i;
            }
            if (mask.charAt(i) == '0') {
                maxZeroIndex = i;
            }
        }
        return minOneIndex + 1 == maxZeroIndex;
    }

    static boolean isValid(int n) {
        return n >= 0 && n <= 255;
    }
}
全部评论

相关推荐

点赞 评论 收藏
转发
点赞 收藏 评论
分享
牛客网
牛客企业服务