牛客网力扣算法编程之八 | 字符串 - 识别有效的IP地址和掩码并进行分类统计-Java代码实现

【算法编程】识别有效的IP地址和掩码并进行分类统计

一.题目描述
        请解析IP地址和对应的掩码,进行分类识别。要求按照A/B/C/D/E类地址归类,不合法的地址和掩码单独归类。

所有的IP地址划分为 A,B,C,D,E五类
A类地址1.0.0.0~126.255.255.255;
B类地址128.0.0.0~191.255.255.255;
C类地址192.0.0.0~223.255.255.255;
D类地址224.0.0.0~239.255.255.255;
E类地址240.0.0.0~255.255.255.255

私网IP范围是:
10.0.0.0-10.255.255.255
172.16.0.0-172.31.255.255
192.168.0.0-192.168.255.255

子网掩码为二进制下前面是连续的1,然后全是0。(例如:255.255.255.32就是一个非法的掩码)
注意二进制下全是1或者全是0均为非法

注意:
1. 类似于【0.*.*.*】和【127.*.*.*】的IP地址不属于上述输入的任意一类,也不属于不合法ip地址,计数时请忽略
2. 私有IP地址和A,B,C,D,E类地址是不冲突的

输入描述:
多行字符串。每行一个IP地址和掩码,用~隔开。
输出描述:
统计A、B、C、D、E、错误IP地址或错误掩码、私有IP的个数,之间以空格隔开。

示例1
输入:
10.70.44.68~255.254.255.0
1.0.0.1~255.0.0.0
192.168.0.2~255.255.255.0
19..0.~255.255.255.0

输出:
1 0 1 0 0 2 1

示例2
输入:
0.201.56.50~255.255.111.255
127.201.56.50~255.255.111.255

输出:
0 0 0 0 0 0 0

说明:类似于【0.*.*.*】和【127.*.*.*】的IP地址不属于上述输入的任意一类,也不属于不合法ip地址,计数时请忽略

二.  解题思路总结:

本题的困难点在于读懂题目以及对子网掩码的判断上,逻辑有点绕;

1.对输入按~分割字符串,字符串数组保存IP地址IPAddr及子网掩码sub,保存IP地址的第一段数字,用于判断范围;

2. 整数A,B,C,D,E,Err,Pri分别用于统计A,B,C ,D,E,错误地址或子网掩码,私有IP地址;

3.A,B,C,D,E段有效地址:首段满足p[0]范围要求 & 其余字段长度大于0 & 子网掩码合法

在A,B,C有效地址中,顺便处理私有地址;

4. 0和127开头的IP地址不计算;

5.其余均为错误IP地址;

6.子网掩码的有效性判断,结合数组{"254", "252", "248", "240", "224", "192", "128"}比对进行判断。注意

子网掩码为二进制下前面是连续的1,然后全是0。(例如:255.255.255.32就是一个非法的掩码)

注意二进制下全是1或者全是0均为非法。

三.  Java代码如下:

import java.util.*;
public class Main {
 public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int A=0,B=0,C=0,D=0,E=0,Erro=0,Pri=0;
        while (sc.hasNextLine()) {
            String str = sc.nextLine();
            String[] IP = str.split("\\~");  //按~分割字符串
            String IP0 = IP[0];  
            String IP1 = IP[1];
            String[] IPAddr = IP0.split("\\."); //保存IP地址
            int[] p = new int[2];
            p[0] = Integer.parseInt(IPAddr[0]); //保存IP地址的第一段数字,用于判断范围
            String[] sub = IP1.split("\\.");   //保存子网掩码
            boolean flag = secondNum(sub); //调用函数判断是否合法
                if (p[0] >= 1 && p[0] <= 126 && IPAddr[1].length() >= 1 && IPAddr[2].length() >= 1 && IPAddr[3].length() >= 1
                        && flag==true) {    //A段有效地址
                       A++;                        
                    if ((IPAddr[0].equals("10")))  
                        Pri++;             //同时也是私有IP地址
                }
                else if (p[0] >= 128 && p[0] <= 191 && IPAddr[1].length() >= 1 && IPAddr[2].length() >= 1 && IPAddr[3].length() >= 1
                        && flag==true) {   //B段有效地址
                    B++;
                    if (IPAddr[0].equals("172") && Integer.parseInt(IPAddr[1]) >= 16 &&Integer.parseInt(IPAddr[1]) <= 31)
                        Pri++;                //同时也是有效私有IP地址
                } else if (p[0] >= 192 && p[0] <= 223 && IPAddr[1].length() >= 1 && IPAddr[2].length() >= 1 && IPAddr[3].length() >= 1
                        && flag==true) {     //C段有效地址
                    C++;
                    if (IPAddr[0].equals("192") && IPAddr[1].equals("168"))     Pri++; //同时也是私有IP地址
                } 
               else if (p[0] >= 224 && p[0] <= 239 && IPAddr[1].length() >= 1 && IPAddr[2].length() >= 1 && IPAddr[3].length() >= 1
                        && flag==true) D++;    //D段有效地址
                else if (p[0] >= 240 && p[0] <= 255 && IPAddr[1].length() >= 1 && IPAddr[2].length() >= 1 && IPAddr[3].length() >= 1
                        && flag==true) E++;    //E段有效地址
                else if (IPAddr[0].equals("0") || IPAddr[0].equals("127")) continue; //0和127开头的IP地址不计算
                else Erro++;   //其余为错误IP地址
            }
            System.out.println(A+" "+B+" "+ C+" "+D+" "+ E+" "+ Erro+" "+Pri);
        }
    //判断掩码是否合法
    public static boolean secondNum(String[] arr){
        String[] str = {"254", "252", "248", "240", "224", "192", "128"};//二进制以1开头的数组
        //判断掩码
        if (arr[0].equals("255")) {   逐级判断是否是合法子网掩码
            if (arr[1].equals("255")) {
                if (arr[2].equals("255")) {
                    if (Arrays.asList(str).contains(arr[3])) {
                        return true;
                    } else if (arr[3].equals("0")) {
                        return true;
                    } else {
                        return false;
                    }
                } else if (Arrays.asList(str).contains(arr[2])) {
                    if (arr[3].equals("0")) {
                        return true;
                    } else {
                        return false;
                    }
                } else if (arr[2].equals("0") && arr[3].equals("0")) {
                    return true;
                } else {
                    return false;
                }
            } else if (Arrays.asList(str).contains(arr[1])) {
                if (arr[2].equals("0") && arr[3].equals("0")) {
                    return true;
                } else {
                    return false;
                }
            } else if (arr[1].equals("0") && arr[2].equals("0") && arr[3].equals("0")) {
                return true;
            } else {
                return false;
            }
        } else if (Arrays.asList(str).contains(arr[0])) {
            if (arr[1].equals("0") && arr[2].equals("0") && arr[3].equals("0")) {
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

国林哥

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

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

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

打赏作者

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

抵扣说明:

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

余额充值