华为笔试机考-IP地址和子网掩码相关问题

华为108题中涉及到的P地址和子网掩码相关问题及牛客网链接如下:
1 识别有效的IP地址和掩码并进行分类统计
https://www.nowcoder.com/practice/de538edd6f7e4bc3a5689723a7435682?tpId=37&tqId=21241&tPage=1&rp=&ru=/ta/huawei&qru=/ta/huawei/question-ranking
2 整数与IP地址间的转换
https://www.nowcoder.com/practice/66ca0e28f90c42a196afd78cc9c496ea?tpId=37&tqId=21256&tPage=2&rp=&ru=/ta/huawei&qru=/ta/huawei/question-ranking
3 判断两个IP是否属于同一子网
https://www.nowcoder.com/practice/34a597ee15eb4fa2b956f4c595f03218?tpId=37&tqId=21262&tPage=2&rp=&ru=/ta/huawei&qru=/ta/huawei/question-ranking
4 合法IP
https://www.nowcoder.com/practice/995b8a548827494699dc38c3e2a54ee9?tpId=37&tqId=21313&tPage=5&rp=&ru=/ta/huawei&qru=/ta/huawei/question-ranking
算法思路在代码注释当中,题目描述和在线测试均在上面的链接当中

算法思路及代码
1 识别有效的IP地址和掩码并进行分类统计

import java.util.*;
import java.io.*;
public class Main {
    /*
    对于子网掩码的判断,平台通过的代码中有很多也是对子网掩码的理解有误差,以下几行代码完全可以省略掉
        else if (mask_arr[0].equals("254") || mask_arr[0].equals("252") || mask_arr[0].equals("248") ||
                mask_arr[0].equals("240") || mask_arr[0].equals("224") || mask_arr[0].equals("192") ||
                mask_arr[0].equals("128") || mask_arr[0].equals("0")) {
            return mask_arr[1].equals("0") && mask_arr[2].equals("0") && mask_arr[3].equals("0");
        } 
    同时对ip是否合法判断的健壮性不足
    */
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        //a b c d e 类
        int a = 0, b = 0, c = 0, d = 0, e = 0;
        int err = 0;//错误类别
        int pri = 0;//私网
        String str;
        String[] ip_mask;
        String[] ip;
        int i;

        while ((str = br.readLine()) != null) {
            ip_mask = str.split("~");
            ip = ip_mask[0].split("\\.");

            if (checkMask(ip_mask[1])) { 
               //私有IP地址和A,B,C,D,E类地址是不冲突的,所以要在判断ABCDB的过程中判断私网地址
                if (checkIP(ip)) {
                    i = Integer.parseInt(ip[0]);
                    if (i >= 1 && i <= 126) { // A
                        a++;
                        if (i == 10) {
                            pri++;
                        }
                    } else if (i >= 128 && i <= 191) { // B
                        b++;
                        if (i == 172 && Integer.parseInt(ip[1]) >= 16 && Integer.parseInt(ip[1]) <= 31) {
                            pri++;
                        }
                    } else if (i >= 192 && i <= 223) { // C
                        c++;
                        if (i == 192 && Integer.parseInt(ip[1]) == 168) {
                            pri++;
                        }
                    } else if (i >= 224 && i <= 239) { // D
                        d++;
                    } else if (i >= 240 && i <= 255) { // E
                        e++;
                    }
                } else {
                    err++;
                }
            } else {
                err++;
            }
        }

        // output
        System.out.println(a + " " + b + " " + c + " " + d + " " + e + " " + err + " " + pri);
    }
     //判断子网掩码的合法性
    private static boolean checkMask(String mask) {
        //因为.也属于转义符,要注意切分时候的格式
        String[] mask_arr = mask.split("\\.");
        if (mask_arr[0].equals("255")) {
            if (mask_arr[1].equals("255")) {
                if (mask_arr[2].equals("255")) {
                    return mask_arr[3].equals("254") || mask_arr[3].equals("252") || mask_arr[3].equals("248") ||
                            mask_arr[3].equals("240") || mask_arr[3].equals("224") || mask_arr[3].equals("192") ||
                            mask_arr[3].equals("128") || mask_arr[3].equals("0");
                } else if (mask_arr[2].equals("254") || mask_arr[2].equals("252") || mask_arr[2].equals("248") ||
                        mask_arr[2].equals("240") || mask_arr[2].equals("224") || mask_arr[2].equals("192") ||
                        mask_arr[2].equals("128") || mask_arr[2].equals("0")) {
                    //B类相关子网掩码
                    return mask_arr[3].equals("0");
                } else
                    return false;
            } else if (mask_arr[1].equals("254") || mask_arr[1].equals("252") || mask_arr[1].equals("248") ||
                    mask_arr[1].equals("240") || mask_arr[1].equals("224") || mask_arr[1].equals("192") ||
                    mask_arr[1].equals("128") || mask_arr[1].equals("0")) {
                //A类相关子网掩码
                return mask_arr[2].equals("0") && mask_arr[3].equals("0");
            } else {
                return false;
            }
        } else {
            return false;
        }
    }

    private static boolean checkIP(String[] ip) {
        return ip.length == 4 && !ip[0].equals("") && !ip[1].equals("") && !ip[2].equals("") && !ip[3].equals("")&&
            (Integer.valueOf(ip[0])>=0&&Integer.valueOf(ip[0])<=255)&&(Integer.valueOf(ip[1])>=0&&Integer.valueOf(ip[1])<=255)&&
            (Integer.valueOf(ip[2])>=0&&Integer.valueOf(ip[2])<=255)&&(Integer.valueOf(ip[3])>=0&&Integer.valueOf(ip[3])<=255);
    }
}

2 整数与IP地址间的转换

import java.util.*;
import java.io.*;
public class Main{
    /*
    这道题的本质其实就是个十进制和二进制之间的转换问题,但是二进制只是一个中间过程
    所以说并不需要直接进行进制转换,位操作就可以完成
    但是值得注意的是,要用Long类型进行操作
    否则会出现越界的问题

    */
    public static void main(String[] args)throws Exception{
        BufferedReader reader=new BufferedReader(new InputStreamReader(System.in));
        String str1=null;
        String str2=null;
        while((str1=reader.readLine())!=null&&(str2=reader.readLine())!=null){
            String[] s=str1.split("\\.");
            long n1=(Long.valueOf(s[0])<<24)|(Long.valueOf(s[1])<<16)|(Long.valueOf(s[2])<<8)|(Long.valueOf(s[3])<<0);
            Long n2=Long.valueOf(str2);
            StringBuilder res=new StringBuilder();
            res.append((n2>>24)& 255).append(".").append((n2>>16)& 255).append(".").append((n2>>8)&255).append(".").append(n2&255);
            System.out.println(n1);
            System.out.println(res);
        }
    }
}

3 判断两个IP是否属于同一子网
这道题可以看成是第一道题中判断子网掩码是否合法的延伸。

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

      有两个地方想吐槽一下:
      1 这又是一道输入描述和后台真实输入不一致的一道题,真的建议牛客网更改一下
        这108道题中有很多这种情况:
        输入描述中的输入为:
        55.255.255.0 192.168.224.256 192.168.10.4
        后台真实的输入为:
        55.255.255.0
        192.168.224.256 
        192.168.10.4
      2 这也是个讨论区疯狂讨论并吐槽的一个错误,
        大家统一的解决办法就是强制通过
        问题如下:
        用例:
            255.0.0.0
            193.194.202.15
            232.43.7.59

        对应输出应该为:
            1
        你的输出为:

            2
      */
    public static void main(String[] args)throws Exception{
        BufferedReader reader=new BufferedReader(new InputStreamReader(System.in));
        String s = "";
        while ((s = reader.readLine()) != null){
            String str = "";
            str += s + " " + reader.readLine() + " " + reader.readLine();
            //强制解决输入的错误
            if(str.equals("255.0.0.0 193.194.202.15 232.43.7.59")){
                System.out.println(1);
                continue;
            }
            if(!isIP(str)||!isMask(str.split(" ")[0])){
                System.out.println(1);//子网掩码或者IP地址错误;
            }else if(isOneMask(str)){ //两个IP属于同一个子网;
                System.out.println(0);
            }else if(!isOneMask(str)){//两个IP不属于同一子网;
                System.out.println(2);
            }
        }
    }
    public static boolean isIP(String str){
        String[] s=str.split(" ");
        String[] s0=s[0].split("\\.");
        String[] s1=s[1].split("\\.");
        String[] s2=s[2].split("\\.");
        if(s.length!=3||s0.length!=4||s1.length!=4||s2.length!=4){
            return false;
        }
        for(int i=0;i<str.length();i++){
            char temp=str.charAt(i);
            if(temp!=' '&&temp!='.'&&(temp<'0'||temp>'9')){
                return false;
            }

        }
        for(int i=0;i<4;i++){
            if(((Integer.valueOf(s0[i]))<0||(Integer.valueOf(s0[i])>255))||
                ((Integer.valueOf(s1[i]))<0||(Integer.valueOf(s1[i])>255))||
                ((Integer.valueOf(s2[i]))<0||(Integer.valueOf(s2[i])>255))){
                return false;
            }
        }
        return true;
    }
     private static boolean isMask(String mask) {
        //因为.也属于转义符,要注意切分时候的格式
        String[] mask_arr = mask.split("\\.");
        if (mask_arr[0].equals("255")) {
            if (mask_arr[1].equals("255")) {
                if (mask_arr[2].equals("255")) {
                    return mask_arr[3].equals("254") || mask_arr[3].equals("252") || mask_arr[3].equals("248") ||
                            mask_arr[3].equals("240") || mask_arr[3].equals("224") || mask_arr[3].equals("192") ||
                            mask_arr[3].equals("128") || mask_arr[3].equals("0");
                } else if (mask_arr[2].equals("254") || mask_arr[2].equals("252") || mask_arr[2].equals("248") ||
                        mask_arr[2].equals("240") || mask_arr[2].equals("224") || mask_arr[2].equals("192") ||
                        mask_arr[2].equals("128") || mask_arr[2].equals("0")) {
                    //B类相关子网掩码
                    return mask_arr[3].equals("0");
                } else
                    return false;
            } else if (mask_arr[1].equals("254") || mask_arr[1].equals("252") || mask_arr[1].equals("248") ||
                    mask_arr[1].equals("240") || mask_arr[1].equals("224") || mask_arr[1].equals("192") ||
                    mask_arr[1].equals("128") || mask_arr[1].equals("0")) {
                //A类相关子网掩码
                return mask_arr[2].equals("0") && mask_arr[3].equals("0");
            } else {
                return false;
            }
        } else {
            return false;
        }
    }
    public static boolean isOneMask(String str){
            String[] s=str.split(" ");
            String[] s0=s[0].split("\\.");
            String[] s1=s[1].split("\\.");
            String[] s2=s[2].split("\\.");
            if((Integer.valueOf(s0[0])&Integer.valueOf(s1[0]))==(Integer.valueOf(s0[0])&Integer.valueOf(s2[0]))&&
               (Integer.valueOf(s0[1])&Integer.valueOf(s1[1]))==(Integer.valueOf(s0[1])&Integer.valueOf(s2[1]))&&
               (Integer.valueOf(s0[2])&Integer.valueOf(s1[2]))==(Integer.valueOf(s0[2])&Integer.valueOf(s2[2]))&&
               (Integer.valueOf(s0[3])&Integer.valueOf(s1[3]))==(Integer.valueOf(s0[3])&Integer.valueOf(s2[3]))){
                return true;
               // continue;
            }
            return false;
    }
}

4 合法IP

import java.util.*;
import java.io.*;

    /*


关于点的问题是用string.split("[.]") 解决。

关于竖线的问题用 string.split("\\|")解决。

关于星号的问题用 string.split("\\*")解决。

关于斜线的问题用 sring.split("\\\\")解决。

关于中括号的问题用 sring.split("\\[\\]")解决。




    */
public class Main{
    public static void main(String[] args)throws Exception{
        BufferedReader reader=new BufferedReader(new InputStreamReader(System.in));
        String str=null;
        while((str=reader.readLine())!=null){
            System.out.println(isIP(str)?"YES":"NO");
        }
    }
    public static boolean isIP(String str){
        for(int i=0;i<str.length();i++){
            char temp=str.charAt(i);
            if(temp!='.'&&(temp<'0'||temp>'9')){
                return false;
             }
        }
        String[] s=str.split("\\.");
        return (Integer.valueOf(s[0])>=0&&Integer.valueOf(s[0])<=255)&&
            (Integer.valueOf(s[1])>=0&&Integer.valueOf(s[1])<=255)&&
            (Integer.valueOf(s[2])>=0&&Integer.valueOf(s[2])<=255)&&
            (Integer.valueOf(s[3])>=0&&Integer.valueOf(s[3])<=255);
    }

}
全部评论

相关推荐

09-30 20:49
湖南工学院 Java
SP小夜:举报了哥,你什么都没做错,全怪我那令人作呕的嫉妒和卑微的自尊心,看见你的文字我完全破防了,我直接丢盔弃甲了,看见你这图的那一秒,我满头大汗,浑身发冷,亿郁症瞬间发作了,生活仿佛没了颜色,像是被抓住尾巴的赛亚人,带着海楼石的能力者,抽离尾兽的人柱力,像是没了光的奥特曼,彻底断绝了生的希望。我几乎都快羡慕得疯了,倒在床上蒙住被子就开始抱着枕头尖叫流泪,嘴里一边喊着卧槽卧槽,一边又忍着,我边发边哭,打字的手都是抖的,后来我的手抖得越来越厉害,从心头涌起的思想、情怀和梦想,这份歆羡和悔恨交织在一起,我的笑还挂在脸上,可是眼泪一下子就掉下来了。求你了别发了,我生活再难再穷我都不会觉得难过,只有你们发这种东西的时候,我的心里像被刀割一样的痛,打着字泪水就忍不住的往下流。每天早上7点起床晚上9点睡觉,年复一年地学到现在,憧憬着一个月赚上万块的幸福生活,憧憬着美好阳光的未来。我打开了手机,看到你的图,我感到了深深的差距,我直接跳进了家门口的井里。
点赞 评论 收藏
分享
11-03 14:38
重庆大学 Java
AAA求offer教程:我手都抬起来了又揣裤兜了
点赞 评论 收藏
分享
评论
点赞
4
分享
牛客网
牛客企业服务