华为机试刷题笔记HJ39-判断两个IP是否属于同一子网

Posted IceSugarJJ

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了华为机试刷题笔记HJ39-判断两个IP是否属于同一子网相关的知识,希望对你有一定的参考价值。

题目描述

IP地址是由4个0-255之间的整数构成的,用"."符号相连。
二进制的IP地址格式有32位,例如:10000011,01101011,00000011,00011000;每八位用十进制表示就是131.107.3.24
子网掩码是用来判断任意两台计算机的IP地址是否属于同一子网络的根据。
子网掩码与IP地址结构相同,是32位二进制数,由1和0组成,且1和0分别连续,其中网络号部分全为“1”和主机号部分全为“0”。
你可以简单的认为子网掩码是一串连续的1和一串连续的0拼接而成的32位二进制数,左边部分都是1,右边部分都是0。
利用子网掩码可以判断两台主机是否在同一子网中。
若两台主机的IP地址分别与它们的子网掩码进行逻辑“与”运算(按位与/AND)后的结果相同,则说明这两台主机在同一子网中。

示例:
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地址,判断这两个ip地址是否是一个子网络。
若IP地址或子网掩码格式非法则输出1,若IP1与IP2属于同一子网络输出0,若IP1与IP2不属于同一子网络输出2。
注:
有效掩码与IP的性质为:

  1. 掩码与IP每一段在 0 - 255 之间
  2. 掩码的二进制字符串前缀为网络号,都由‘1’组成;后缀为主机号,都由’0’组成

输入描述:
3行输入,第1行是输入子网掩码、第2,3行是输入两个ip地址
题目的示例中给出了三组数据,但是在实际提交时,你的程序可以只处理一组数据(3行)。

输出描述:
若IP地址或子网掩码格式非法则输出1,若IP1与IP2属于同一子网络输出0,若IP1与IP2不属于同一子网络输出2

示例1

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

题解

下面展示本人题解思路代码。

const rl = require("readline").createInterface( input: process.stdin )
var iter = rl[Symbol.asyncIterator]()
const readline = async () => (await iter.next()).value

void async function () 
  while (maskIP = await readline()) 
    let IP1 = await readline()
    let IP2 = await readline()

    let arrMask = maskIP.split('.')
    let arrIP1 = IP1.split('.')
    let arrIP2 = IP2.split('.')

    // 判断是否合法

    if (isValidIP(arrIP1) && isValidIP(arrIP2) && isValidMask(arrMask)) 
      // 判断是否在同一子网络
      isSameSubnet(arrIP1, arrIP2, arrMask)
     else 
      console.log(1)
    
  
()

function isValidIP (arr) 
  for (let i = 0; i < 4; i++) 
    if (Number(arr[i]) < 0 || Number(arr[i]) > 255) 
      return false
    
  
  return true

function isValidMask (arr) 
  for (let i = 0; i < 4; i++) 
    if (arr[i] < 0 || arr[i] > 255) 
      return false
     else 
      arr[i] = Number(arr[i]).toString(2)
      if (arr[i].length != 8) 
        // 此处已将子网掩码转换为了二进制字符串
        arr[i] = arr[i].padStart(8, '0')
      
    
  
  let str = arr.join('')
  if (str.indexOf('01') == -1) 
    return true
   else 
    return false
  


function isSameSubnet (arrIP1, arrIP2, arrMask) 
  let result1 = []
  let result2 = []
  for (let i = 0; i < 4; i++) 
    arrIP1[i] = Number(arrIP1[i]).toString(2)
    if (arrIP1[i].length != 8) 
      arrIP1[i] = arrIP1[i].padStart(8, '0')
    
    arrIP2[i] = Number(arrIP2[i]).toString(2)
    if (arrIP2[i].length != 8) 
      arrIP2[i] = arrIP2[i].padStart(8, '0')
    

    result1[i] = parseInt(arrIP1[i] & arrMask[i])
    result2[i] = parseInt(arrIP2[i] & arrMask[i])

  
  if (result1.join() == result2.join()) 
    console.log(0)
   else 
    console.log(2)
  

文章系原创,在阅读过程中如若有误,劳请指正;如若有妙解、疑惑也欢迎大家和我交流,感谢!

华为OJ075-判断两个IP是否属于同一子网

【华为OJ】【算法总篇章】


【华为OJ】【075-判断两个IP是否属于同一子网】

【工程下载】


题目描述

    子网掩码是用来判断任意两台计算机的IP地址是否属于同一子网络的根据。
    子网掩码与IP地址结构相同,是32位二进制数,其中网络号部分全为“1”和主机号部分全为“0”。利用子网掩码可以判断
两台主机是否中同一子网中。若两台主机的IP地址分别与它们的子网掩码相“与”后的结果相同,则说明这两台主机在同一子网中。

示例:
IP地址        192.168.0.1
子网掩码       255.255.255.0
转化为二进制进行运算:
IP地址        11010000.10101000.00000000.00000001
子网掩码      11111111.11111111.11111111.00000000
AND运算
             11000000.10101000.00000000.00000000
转化为十进制后为:
             192.168.0.0

IP地址         192.168.0.254
子网掩码        255.255.255.0
转化为二进制进行运算:
IP地址        11010000.10101000.00000000.11111110
子网掩码       11111111.11111111.11111111.00000000
AND运算
              11000000.10101000.00000000.00000000
转化为十进制后为:
              192.168.0.0

    通过以上对两台计算机IP地址与子网掩码的AND运算后,我们可以看到它运算结果是一样的。均为192.168.0.0,
所以这二台计算机可视为是同一子网络。
/**
 * 功能: 判断两台计算机IP地址是同一子网络。
 * 输入参数: String Mask: 子网掩码,格式:“255.255.255.0”;
 *           String ip1: 计算机1的IP地址,格式:“192.168.0.254”;
 *           String ip2: 计算机2的IP地址,格式:“192.168.0.1”;
 *
 * 返回值:0:IP1与IP2属于同一子网络;
 *        1:IP地址或子网掩码格式非法;
 *        2:IP1与IP2不属于同一子网络
 */
public int checkNetSegment(String mask, String ip1, String ip2) {
    /*在这里实现功能*/
    return 0;
}

输入描述

输入子网掩码、两个ip地址

输出描述

得到计算结果

输入例子

255.255.255.0
192.168.224.256
192.168.10.4

输出例子

1

算法实现

import java.util.Scanner;

/**
 * Author: 王俊超
 * Date: 2016-01-03 12:59
 * Declaration: All Rights Reserved !!!
 */
public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
//        Scanner scanner = new Scanner(Main.class.getClassLoader().getResourceAsStream("data.txt"));
        while (scanner.hasNext()) {
            String subnet = scanner.next();
            String ip1 = scanner.next();
            String ip2 = scanner.next();

            System.out.println(subnetJudgement(subnet, ip1, ip2));
        }

        scanner.close();
    }

    private static int subnetJudgement(String subnet, String ip1, String ip2) {

        //  1:IP地址或子网掩码格式非法
        if (!ipValidate(subnet) || !ipValidate(ip1) || !ipValidate(ip2)) {
            return 1;
        }

        int subnetInt = ipStrToInt(subnet);

        //  1:子网掩码格式非法
        if (!subnetMaskValidate(subnetInt)) {
            return 1;
        }

        int b = ipStrToInt(ip2);
        int a = ipStrToInt(ip1);

        // 0:IP1与IP2属于同一子网络
        if ((a & subnetInt) == (b & subnetInt)) {
            return 0;
        }
        // 2:IP1与IP2不属于同一子网络
        else {
            return 2;
        }



    }

    /**
     * 验证IP地址的格式是否正确
     *
     * @param ip IP地址
     * @return true:格式正确,false:格式不正确
     */
    private static boolean ipValidate(String ip) {
        String[] part = ip.split("\\\\.");

//        if (part.length != 4) {
//            return false;
//        }

        for (String s : part) {
            try {
                int num = Integer.parseInt(s);
                if (num < 0 || num > 255) {
                    return false;
                }
            } catch (Exception ex) {
                return false;
            }
        }

        return true;
    }

    /**
     * 子网掩码验证,网络号部分全为“1”和主机号部分全为“0”
     *
     * @param ip
     * @return
     */
    private static boolean subnetMaskValidate(int ip) {
        boolean hasZero = false;
        int and = 0x80000000;
        while (and != 0) {
            // 所处理的位位置为0
            if ((ip & and) == 0) {
                // 说明出现了0
                hasZero = true;
            }
            // 如果位置为1
            else {
                // 之前已经有0出现过,那说明1是不连续的,所以子网掩码不合法
                if (hasZero) {
                    return false;
                }
            }

            // 无符号右移一位
            and >>>= 1;
        }

        return true;
    }

    /**
     * 将点分十进制的IP地址转换成整数表示
     *
     * @param ip 点分十进制的IP地址
     * @return IP地址的整数表
     */
    private static int ipStrToInt(String ip) {
        String[] part = ip.split("\\\\.");
        int intIP = 0;

        for (int i = 0; i < part.length; i++) {
            int t = Integer.parseInt(part[i]);
            intIP += t << (24 - 8 * i);
        }

        return intIP;
    }
}

以上是关于华为机试刷题笔记HJ39-判断两个IP是否属于同一子网的主要内容,如果未能解决你的问题,请参考以下文章

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

华为OJ075-判断两个IP是否属于同一子网

华为机试HJ81:字符串字符匹配

华为机试HJ57:高精度整数加法

华为机试-HJ68 成绩排序

华为机试HJ90:合法IP