华为机试 判断两个IP是否属于同一子网

本文探讨了如何利用子网掩码判断两个IP地址是否属于同一子网,提供了两种解题思路,包括转换为二进制并进行AND运算,以及使用StringBuilder简化十进制转二进制。通过实例展示了如何应用这些方法并解析输入的合规性。
摘要由CSDN通过智能技术生成

一、题目描述

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

子网掩码是用来判断任意两台计算机的IP地址是否属于同一子网络的根据。
子网掩码与IP地址结构相同,是32位二进制数,其中网络号部分全为“1”和主机号部分全为“0”。利用子网掩码可以判断两台主机是否中同一子网中。若两台主机的IP地址分别与它们的子网掩码相“与”后的结果相同,则说明这两台主机在同一子网中。
示例:
I P 地址  192.168.0.1
子网掩码  255.255.255.0
转化为二进制进行运算:
I P 地址  11000000.10101000.00000000.00000001
子网掩码 11111111.11111111.11111111.00000000
AND运算 11000000.10101000.00000000.00000000
转化为十进制后为:
192.168.0.0
I P 地址  192.168.0.254
子网掩码  255.255.255.0
转化为二进制进行运算:
I P 地址 11000000.10101000.00000000.11111110
子网掩码 11111111.11111111.11111111.00000000
AND运算 11000000.10101000.00000000.00000000
转化为十进制后为:
192.168.0.0
通过以上对两台计算机IP地址与子网掩码的AND运算后,我们可以看到它运算结果是一样的。均为192.168.0.0,所以这二台计算机可视为是同一子网络
注:
有效掩码与IP的性质为:
1 掩码与IP每一段在 0 - 255 之间
2 掩码的二进制字符串前缀为网络号,都由‘1’组成;后缀为主机号,都由’0’组成
本题有多组输入

输入描述
多组输入,一组3行,第1行是输入子网掩码、第2,3行是输入两个ip地址
输出描述:
若IP地址或子网掩码格式非法则输出1,若IP1与IP2属于同一子网络输出0,若IP1与IP2不属于同一子网络输出2

实例:

输入
255.255.255.0
192.168.224.256
192.168.10.4
255.0.0.0
193.194.202.15
232.43.7.59
255.255.255.0
192.168.0.254
192.168.0.1
1
2
0
说明:
对于第一个例子:
255.255.255.0
192.168.224.256
192.168.10.4
其中IP:192.168.224.256不合法,输出1
对于第二个例子:
255.0.0.0
193.194.202.15
232.43.7.59
2个与运算之后,不在同一个子网,输出2
对于第三个例子,2个与运算之后,如题目描述所示,在同一个子网,输出0

来源:https://www.nowcoder.com/ta/huawei

二、解题思路一

import java.util.*;

public class Main{
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            String ipLine = sc.nextLine();
            String mask1Line = sc.nextLine();
            String mask2Line = sc.nextLine();
            // 将输入行转换为int数组
            int[] ipArr = intArray(ipLine);
            int[] mask1Arr = intArray(mask1Line);
            int[] mask2Arr = intArray(mask2Line);
            // 检查输入
            boolean result1 = checkIp(ipArr);
            boolean result2 = checkMask(mask1Arr);
            boolean result3 = checkMask(mask2Arr);
            // 输入正确
            if(result1 && result2 && result3) {
                // 将ip 掩码1 掩码2 转换为32位二进制数(倒叙,与顺序无关,主要用于比较)
                int[] ipBinaryArr = convertToBinary(ipArr);
                int[] mask1BinaryArr = convertToBinary(mask1Arr);
                int[] mask2BinaryArr = convertToBinary(mask2Arr);

                // 比较ip与掩码1 掩码2
                compareIpAndMask(ipBinaryArr, mask1BinaryArr, mask2BinaryArr);
            }else { // 输入的不符合规范
                System.out.println("1");
            }
        }
    }

    // 分割字符串,并转换为int数组
    public static int[] intArray(String str){
    	// 转义字符\\
        String[] strArr = str.split("\\.");
        int[] intArr = new int[strArr.length];
        for(int i = 0;i<strArr.length;i++){
            intArr[i] = Integer.parseInt(strArr[i]);
        }
        return intArr;
    }

    //检查ip地址:IP每一段在 0 - 255 之间,前一段要大于后一段
    public static boolean checkIp(int[] arr){
        for(int i = 0;i<arr.length;i++){
            if(i == arr.length - 1){
                if(arr[i] < 0 || arr[i] > 255){
                    return false;
                }
            }else{
                if(arr[i] < 0 || arr[i] > 255 || arr[i] < arr[i+1]){
                    return false;
                }
            }
            
        }
        return true;
    }
    //检查掩码地址:掩码每一段在 0 - 255 之间,前一段要大于等于后一段
    public static boolean checkMask(int[] arr){
        for(int i = 0;i<arr.length;i++) {
            if (arr[i] < 0 || arr[i] > 255) {
                return false;
            }
        }
        return true;
    }

    // 转换为二进制数
    public static int[] convertToBinary(int[] arr){
        int[] binaryArr = new int[arr.length * 8];
        int index = 0;
        for (int i = 0; i < arr.length; i++) {
            int a = arr[i];
            for (int j = 8 * index; j < 8 * index + 8; j++) {
                if (a == 0) {
                    for (int z = j; z < 8 * index + 8; z++) {
                        binaryArr[z] = 0;
                    }
                    break;
                }
                int b = a % 2;
                a /= 2;
                binaryArr[j] = b;
            }
            index++;
        }
        return binaryArr;
    }

    // 比较ip与掩码1 掩码2
    public static void compareIpAndMask(int[] ipBinaryArr, int[] mask1BinaryArr, int[] mask2BinaryArr){
        // 1 1=1  1 0=0  0 0=0
        String ipAndMask1 = "";
        String ipAndMask2 = "";
        for (int i = 0; i < ipBinaryArr.length; i++) {
            if (ipBinaryArr[i] == 1 && mask1BinaryArr[i] == 1) {
                ipAndMask1 += ipBinaryArr[i];
            } else {
                ipAndMask1 += "0";
            }
            if (ipBinaryArr[i] == 1 && mask2BinaryArr[i] == 1) {
                ipAndMask2 += ipBinaryArr[i];
            } else {
                ipAndMask2 += "0";
            }
        }
        if (ipAndMask1.equals(ipAndMask2)) {
            System.out.println("0");
        } else {
            System.out.println("2");
        }
    }
}

三、解题思路二

相比于第一种方法,这里十进制转换为二进制用的是Integer的toBinaryString(int a)方法,用StringBuilder拼接成8位的二进制数

import java.util.*;

public class Main{
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            String ipLine = sc.nextLine();
            String mask1Line = sc.nextLine();
            String mask2Line = sc.nextLine();
            // 将输入行转换为int数组
            int[] ipArr = intArray(ipLine);
            int[] mask1Arr = intArray(mask1Line);
            int[] mask2Arr = intArray(mask2Line);
            // 检查输入
            boolean result1 = checkIp(ipArr);
            boolean result2 = checkMask(mask1Arr);
            boolean result3 = checkMask(mask2Arr);
            // 输入正确
            if (result1 && result2 && result3) {
                // 将ip 掩码1 掩码2 转换为32为二进制数(倒叙,与顺序无关,主要用于比较)
                StringBuilder builder1 = convertToBinary1(ipArr);
                StringBuilder builder2 = convertToBinary1(mask1Arr);
                StringBuilder builder3 = convertToBinary1(mask2Arr);

                // 比较ip与掩码1 掩码2
                compareIpAndMask1(builder1, builder2, builder3);
            } else { // 输入的不符合要求
                System.out.println("1");
            }
        }
    }

    // 分割字符串,并转换为int数组
    public static int[] intArray(String str){
        String[] strArr = str.split("\\.");
        int[] intArr = new int[strArr.length];
        for(int i = 0;i<strArr.length;i++){
            intArr[i] = Integer.parseInt(strArr[i]);
        }
        return intArr;
    }

    //检查ip地址:IP每一段在 0 - 255 之间,前一段要大于后一段
    public static boolean checkIp(int[] arr){
        for(int i = 0;i<arr.length;i++){
            if(i == arr.length - 1){
                if(arr[i] < 0 || arr[i] > 255){
                    return false;
                }
            }else {
                if(arr[i] < 0 || arr[i] > 255 || arr[i] < arr[i+1]){
                    return false;
                }
            }
        }
        return true;
    }

    //检查掩码地址:掩码每一段在 0 - 255 之间
    public static boolean checkMask(int[] arr){
        for(int i = 0;i<arr.length;i++) {
            if (arr[i] < 0 || arr[i] > 255) {
                return false;
            }
        }
        return true;
    }

    // 转换为二进制数  (正序,调用Integer的toBinaryString方法,将十进制数转为二进制数)
    public static StringBuilder convertToBinary1(int[] arr){
        StringBuilder builder = new StringBuilder();
        int[] binaryArr = new int[arr.length * 8];
        int index = 0;
        for (int i = 0; i < arr.length; i++) {
            String s = Integer.toBinaryString(arr[i]);
            for(int j = 8;j>s.length();j--){
                builder.append("0");
            }
            builder.append(s);
        }
        return builder;
    }

     // 比较ip与掩码1 掩码2
    public static void compareIpAndMask1(StringBuilder builder1, StringBuilder builder2, StringBuilder builder3){
        // 1 1=1  1 0=0  0 0=0
        String ipAndMask1 = "";
        String ipAndMask2 = "";
        for (int i = 0; i < builder1.length(); i++) {
            if ("1".equals(builder1.substring(i,i+1)) && "1".equals(builder2.substring(i,i+1))) {
                ipAndMask1 += "1";
            } else {
                ipAndMask1 += "0";
            }
            if ("1".equals(builder1.substring(i,i+1)) && "1".equals(builder3.substring(i,i+1))) {
                ipAndMask2 += "1";
            } else {
                ipAndMask2 += "0";
            }
        }
        if (ipAndMask1.equals(ipAndMask2)) {
            System.out.println("0");
        } else {
            System.out.println("2");
        }
    }
}

四、扩展

  1. split()方法分割字符串时,入参是正则表达式,用*****、+.|等符号进行分割时,需要加转义字符\
  2. 十进制转二进制方法:Integet.toBinaryString(int a);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

chenzm666666

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

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

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

打赏作者

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

抵扣说明:

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

余额充值