首页 > 试题广场 >

识别有效的IP地址和掩码并进行分类统计

[编程题]识别有效的IP地址和掩码并进行分类统计
  • 热度指数:356334 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解

请解析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.0239.255.255.255;

E类地址从240.0.0.0255.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地址和掩码,用~隔开。

请参考帖子https://www.nowcoder.com/discuss/276处理循环输入的问题。


输出描述:

统计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
127.69.131.137~255.70.255.255

输出

1 0 1 0 0 2 1

说明

10.70.44.68~255.254.255.0的子网掩码非法,19..0.~255.255.255.0的IP地址非法,所以错误IP地址或错误掩码的计数为2;
1.0.0.1~255.0.0.0是无误的A类地址;
192.168.0.2~255.255.255.0是无误的C类地址且是私有IP;
127.69.131.137~255.70.255.255 计数忽略
所以最终的结果为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 2 0

说明

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

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);

        // 0-4 : A-E
        // 5-7 : pri
        long[][] range = {
            { ParseIP("1.0.0.0"), ParseIP("126.255.255.255")},
            { ParseIP("128.0.0.0"), ParseIP("191.255.255.255")},
            { ParseIP("192.0.0.0"), ParseIP("223.255.255.255")},
            { ParseIP("224.0.0.0"), ParseIP("239.255.255.255")},
            { ParseIP("240.0.0.0"), ParseIP("255.255.255.255")},
        };

        long[][] private_range = {
            { ParseIP("10.0.0.0"), ParseIP("10.255.255.255")},
            { ParseIP("172.16.0.0"), ParseIP("172.31.255.255")},
            { ParseIP("192.168.0.0"), ParseIP("192.168.255.255")}
        };
        int[] result = new int[7];

        // 注意 hasNext 和 hasNextLine 的区别
        while (in.hasNextLine()) { // 注意 while 处理多个 case
            String input = in.nextLine();
            String ip = input.split("~")[0];
            String mark = input.split("~")[1];
            long ip_bin = ParseIP(ip);
            long mark_bin = ParseIP(mark);

            if (IsIgnore(ip)) {
                continue;
            }
            if (!IsMarkValid(mark_bin)){
                result[5]++;
                continue;
            }

            if (ip_bin == -1) {
                result[5]++;
                continue;
            }
            for (int i = 0; i < range.length; i++) {
                if (ip_bin >= range[i][0] && ip_bin <= range[i][1]) {
                    result[i]++;
                    break;
                }
            }
            for (int i = 0; i < private_range.length; i++) {
                if (ip_bin >= private_range[i][0] && ip_bin <= private_range[i][1]) {
                    result[6]++;
                    break;
                }
            }

        }
        for (int i = 0; i < result.length; i++) {

            System.out.print(result[i] + " ");
        }
    }

    static long ParseIP(String str) {
        String[] list = str.split("\\.");
        if (list.length != 4) {
            return -1;
        }
        for (int i = 0; i < list.length; i++) {
            if (list[i] == "") {
                return -1;
            }
        }

        long result = 0;
        for (int i = 0; i < 4; i++) {
            result |= Long.parseLong(list[i]) << ((3 - i) * 8);
        }

        return result;
    }

    static boolean IsMarkValid(long mark) {
        boolean isZero = true;
        long m = 1;
        if ((m & mark) != 0) {
            return false; // all 1
        }
        for (int i = 0; i < 32; i++) {
            if (!isZero && (m & mark) == 0) {
                return false;
            }

            if ((m & mark) != 0) {
                isZero = false;
            }

            m <<= 1;
        }
        if (isZero == true) {
            return false; // all 0
        }
        return true;
    }

    static boolean IsIgnore(String str) {
        String[] list = str.split("\\.");
        return list[0].equals("127") || list[0].equals("0");
    }
}

发表于 2024-11-18 10:22:17 回复(0)
这个例子,我的答案是14个非法子网掩护,答案是13个,可是我自己看也是感觉是14个啊
225.240.129.203~255.110.255.255
183.181.49.4~255.0.0.0
172.177.113.45~255.0.0.0
176.134.46.246~255.0.0.0
153.63.21.56~255.255.58.255
23.135.167.228~255.0.0.0
204.58.47.149~255.0.0.0
113.33.181.46~255.255.255.0
73.245.52.119~255.255.154.0
23.214.47.71~255.0.0.0
139.124.188.91~255.255.255.100
142.94.192.197~255.0.0.0
53.173.252.202~255.0.0.0
127.201.56.50~255.255.111.255
118.251.84.111~255.0.0.0
130.27.73.170~255.0.0.0
253.237.54.56~255.86.0.0
64.189.222.111~255.255.255.139
148.77.44.147~255.0.0.0
59.213.5.253~255.255.0.0
3.52.119.131~255.255.0.0
213.208.164.145~255.255.0.0
24.22.21.206~255.255.90.255
89.43.34.31~255.0.0.0
9.64.214.75~255.0.0.0
110.156.20.173~255.153.0.0
71.183.242.53~255.255.0.0
119.152.129.100~255.0.0.0
38.187.119.201~255.0.0.0
73.81.221.180~255.255.255.255
73.198.13.199~255.0.15.0
99.42.142.145~255.255.255.0
196.121.115.160~255.0.0.0
226.30.29.206~255.0.0.0
244.248.31.171~255.255.255.255
59.116.159.246~255.0.0.0
121.124.37.157~255.0.0.226
103.42.94.71~255.255.0.0
125.88.217.249~255.255.74.255
73.44.250.101~255.255.255.0

import java.util.Scanner;
import java.util.Arrays;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        // while (in.hasNextInt()) { // 注意 while 处理多个 case
        //     int a = in.nextInt();
        //     int b = in.nextInt();
        //     System.out.println(a + b);
        // }

        int[] result = new int[7];

        while (in.hasNextLine()) {
            String[] data = in.nextLine().split("~");

            //check ip 是否非法, 掩码是否非法
            if(!checkFormat(data)){
                result[5]++ ;
                continue;
            }
            
            //check 是哪一类
            int checkTypeResult = checkType(data[0]);
            if(checkTypeResult != -1){
                result[checkTypeResult]++;
            }
            //check 是否是私有
            result[6] += checkPrivate(data[0]);
        }
        
        System.out.print(result[0]);
        for(int i=1; i<result.length; i++){
            System.out.print(" ");
            System.out.print(result[i]);
        }

    }

    public static boolean checkFormat(String[] data) {
        return checkIp(data[0]) && checkMask(data[1]);
    }

    public static boolean checkIp(String ip) {
        String[] fields = ip.split("[.]");
        if (fields.length != 4) {
            return false;
        }
        for (int i = 0; i < 4; i++) {
            int value = 0;
            try {
                value = Integer.parseInt(fields[i]);
            } catch (Exception e) {
                return false;
            }
            if (value < 0 || value > 255) {
                return false;
            }
        }
        return true;
    }

    public static boolean checkMask(String mask) {
        String[] fields = mask.split("[.]");
        if (mask.equals("255.255.255.255") || mask.equals("0.0.0.0") || fields.length != 4) {
            return false;
        }
        int flag = 0;
        for (int i = 3; i >=0; i--) {
            int value = 0;
            try {
                value = Integer.parseInt(fields[i]);
            } catch (Exception e) {
                return false;
            }
            for(int j =0; j<8; j++){
                int bit = value%2;
                flag = flag | bit;
                if(flag == 1 && bit==0){
                    return false;
                }
                value = value >> 1;
            }
        }
        return true;
    }

    public static int checkType(String ip) {
        int first = Integer.parseInt(ip.split("[.]")[0]);
        if(first>=1 && first<=126){
            return 0;
        }else if(first>=128 && first<=191){
            return 1;
        }else if(first>=192 && first<=223){
            return 2;
        }else if(first>=224 && first<=239){
            return 3;
        }else if(first>=240 && first<=255){
            return 4;
        }else{
            return -1;
        }
    }

    public static int checkPrivate(String ip) {
        String[] fields = ip.split("[.]");
        boolean firstCase = fields[0].equals("10");
        boolean secondCase = fields[0].equals("172") && Integer.parseInt(fields[1])<=31;
        boolean thirdCase = fields[0].equals("192") && fields[1].equals("168");
        return (firstCase || secondCase || thirdCase)? 1: 0;
    }
}


发表于 2024-10-15 23:04:25 回复(2)
import java.util.Arrays;
import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    static int[] ipCount = new int[5];
    static int privateIdCount = 0 ;
    static int errors = 0 ;
    static String sMac = ",0,128,192,224,240,248,252,254,255,";
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        while (in.hasNext()) { // 注意 while 处理多个 case
            String ip = in.nextLine();
            ipIsLegal(ip.split("~")[0], ip.split("~")[1]);
        }
        System.out.print(
            ipCount[0] + " " + ipCount[1] + " " + ipCount[2] + " " + ipCount[3] + " " +
            ipCount[4] + " " + errors + " " + privateIdCount
        );
    }
    /**
      * 判断ip是否合法
      */
    private static void ipIsLegal(String ip, String mac) {

        String regex =
            "([1-9]?\\d|1\\d{2}|2[0-4]\\d|25[0-5])(\\.([1-9]?\\d|1\\d{2}|2[0-4]\\d|25[0-5])){3}$";
        ;

        if (ip.startsWith("0") || ip.startsWith("127")) {
            return;
        }
        if (!Pattern.matches(regex, ip) || !macIsLegal(mac) || mac.endsWith("255") ||
                mac.startsWith("0") || ip.split("\\.").length != 4) {
            errors ++ ;
            return;
        };
        int ip0 = Integer.parseInt(ip.split("\\.")[0]);
        int ip1 = Integer.parseInt(ip.split("\\.")[1]);
        if (0 < ip0 && ip0 < 127) {
            if (10 == ip0) {
                privateIdCount++;
            }
            ipCount[0] += 1;
        } else if (127 < ip0 && ip0 < 192) {
            if (172 == ip0 && (15 < ip1 && ip1 < 32)) {
                privateIdCount++;
            }
            ipCount[1] += 1;
        } else if (192 <= ip0 && ip0 < 224) {
            if (192 == ip0 && 168 == ip1) {
                privateIdCount++;
            }
            ipCount[2] += 1;
        } else if (224 <= ip0 && ip0 < 240) {
            ipCount[3] += 1;
        } else if (240 <= ip0 && ip0 < 256) {
            ipCount[4] += 1;
        }
    }
    /**
      判断子网是否合法
      */
    private static boolean macIsLegal(String mac) {
        String[] ss = mac.split("\\.");
        if (ss.length != 4) {
            return false;
        }
        for (String s : ss) {
            if ("".equals(s) || !sMac.contains(","+s+",")) {
                return false;
            }
        }
        return Arrays.stream(ss).map(s1->Integer.toBinaryString(Integer.parseInt(
                                         s1))).collect(Collectors.joining("")).replaceAll("1+", "1").replaceAll("0+",
                                                 "0").length() == 2;
    }


}

发表于 2024-09-05 20:18:23 回复(0)
import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int aIP = 0,bIP = 0,cIP = 0,dIP = 0,eIP = 0,wrongIP = 0,privateIP = 0;
        while(sc.hasNext()) {
            boolean flag = true;//标识是否错误IP,用来跳过其他校验
            String input = sc.nextLine();
            String ip = input.split("~")[0];
            String subnet = input.split("~")[1];
            if(subnet.equals("255.255.255.255") || subnet.equals("0.0.0.0")) {
                wrongIP++;
                flag=false;
            }
            String[] subnetUnit = subnet.split("\\.");
            String[] ips = ip.split("\\.");
            if(subnetUnit.length!=4 || ips.length!=4) {
                wrongIP++;
                flag = false;
            }
            if(ips[0].equals("0") || ips[0].equals("127")){
                continue;
            }
            if(flag) {
                for(int i=3; i>=0; i--) {
                    if(Integer.valueOf(subnetUnit[i])>255 || Integer.valueOf(subnetUnit[i])<0) {
                        wrongIP++;
                        flag = false;
                    }
                    if(Integer.valueOf(ips[i])>255 || Integer.valueOf(ips[i])<0) {
                        wrongIP++;
                        flag = false;
                    }
                }
            }
            if(flag && !isMask(subnetUnit)) {
                wrongIP++;
                flag = false;
            }
            if(flag) {
                for(int i=3; i>=0; i--) {
                    if(ips[i].equals("")) {
                        wrongIP++;
                        flag = false;
                        break;
                    }
                }
            }
            if(flag) {
                if(ips[0].equals("192") && ips[1].equals("168")) privateIP++;
                if(ips[0].equals("172") && Integer.valueOf(ips[1])>=16 && Integer.valueOf(ips[1])<=31) privateIP++;
                if(ips[0].equals("10")) privateIP++;
                if(Integer.valueOf(ips[0])>=240) eIP++;
                else if(Integer.valueOf(ips[0])>=224) dIP++;
                else if(Integer.valueOf(ips[0])>=192) cIP++;
                else if(Integer.valueOf(ips[0])>=128) bIP++;
                else if(Integer.valueOf(ips[0])>=1 && Integer.valueOf(ips[0])<127) aIP++;
            }
        }
        System.out.println(aIP+" "+bIP+" "+cIP+" "+dIP+" "+eIP+" "+wrongIP+" "+privateIP);
    }
     
    public static boolean isMask(String[] subnetUnit) {
        String[] rightSubnet = new String[]{"128","192","224","240","248","252","254","255"};
        for(int i=3; i>=0; i--) {
            if(rightSubnet[i].equals("")) return false;
            if(subnetUnit[i].equals("0")) continue;
            else if(i==0) {
                if(!Arrays.asList(rightSubnet).contains(subnetUnit[i]))
                    return false;
            } else {
                if(!Arrays.asList(rightSubnet).contains(subnetUnit[i])) {
                    return false;
                }
                for(int j=0; j<i; j++) {
                    if(!subnetUnit[j].equals("255"))
                        return false;
                }
                 
            }
        }
        return true;
    }
}

发表于 2024-08-29 09:36:28 回复(0)
import java.util.*;

public class Main {
    
    public static void main(String[] args) {

        Scanner in = new Scanner(System.in);
        // 统计A、B、C、D、E、错误IP地址或错误掩码、私有IP的个数,之间以空格隔开。
        // 【0.*.*.*】和【127.*.*.*】
        int a=0,b=0,c=0,d=0,e=0,f=0,s=0;

        while (in.hasNext()) { //  while 处理多个 case
            //获取ip地址,掩码用字符串数组ips和yms存储
            String str = in.nextLine();
            String [] strs = str.split("~");
            String[] ips =strs[0].split("\\.");
            String[] yms =strs[1].split("\\.");

            //过滤掉非法长度IP地址
            if(ips.length!=4){f++;}
            //过滤掉0.*.*.*】和【127.*.*.*】的IP地址
            else if(!ips[0].equals("0")&&!ips[0].equals("127")){
                boolean bl =true;  //表示合法IP地址

                //是否为合法IP地址
                for (int i = 0; i < 4; i++) {
                    int t =Integer.parseInt(ips[i]);
                    if(t<0||t>255){f++;bl=false;break;}
                }
                //是否为合法掩码
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < 4; i++) {
                    int ym =Integer.parseInt(yms[i]);
                    for (int j = 7; j >= 0; j--) {
                        if ((ym&(1<<j))>0){sb.append("1");}else {sb.append("0");}
                    }
                }
                int count0=0;
                int count1=0;
                for (int i = 0; i < sb.length(); i++) {
                    if(sb.charAt(i)=='0')count0++;
                    if(sb.charAt(i)=='1')count1++;
                    if((i!=sb.length()-1)&&sb.charAt(i)<sb.charAt(i+1)){f++;bl=false;break;}
                }
                if(count0==sb.length()||count1==sb.length()){f++;bl=false;}
                //合法IP地址属于哪一类
                if(bl){
                    int t =Integer.parseInt(ips[0]);
                    int v =Integer.parseInt(ips[1]);
                    if(t<=126&&t>=1){a++;if(t==10)s++;}
                    else if(t<=191&&t>=127){b++;if(t==172&&v==16)s++;}
                    else if(t<=223&&t>=192){c++;if(t==192&&v==168)s++;}
                    else if(t<=239&&t>=224){d++;}
                    else if(t<=255&&t>=240){e++;}
                }
            }

        }
        //输出
        System.out.print(a+" ");
        System.out.print(b+" ");
        System.out.print(c+" ");
        System.out.print(d+" ");
        System.out.print(e+" ");
        System.out.print(f+" ");
        System.out.print(s);
    }
}

发表于 2024-08-18 13:18:59 回复(0)
import java.util.Scanner;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) throws IOException {
        //A,B,C,D,E,错误IP地址或错误掩码,私有IP的个数
        //0,1,2,3,4,5                ,6
        int[] result = new int[7];
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String next = null;
        // 注意 hasNext 和 hasNextLine 的区别
        while ((next = br.readLine()) != null) {
            if ("over".equals(next)) {
                break;
            }
            String[] ipAndYanma = next.split("~");
            String[] ip = ipAndYanma[0].split("\\.");
            String[] netmask = ipAndYanma[1].split("\\.");
            int[] rightMask = new int[8];
            rightMask[7] = 0;
            rightMask[0] = 128;
            rightMask[1] = 192;
            rightMask[2] = 224;
            rightMask[3] = 240;
            rightMask[4] = 248;
            rightMask[5] = 252;
            rightMask[6] = 254;

//            StringBuilder rightMask = new StringBuilder("128 192 224 240 248 252 254");
            //判断IP是否正确
            if (validateIp(ip, result)) continue;

            //排除类似于【0.*.*.*】和【127.*.*.*】的IP地址
            if (checkPrivate(ip)) continue;

            //子网掩码合法性判断
            if (validateNetMask(netmask, result, rightMask)) continue;

            //A B C D E类网址判断
            matchABCDE(ip, result);

            //私网IP判断
            matchPrivateIp(ip, result);
        }
        System.out.println(result[0] + " " + result[1] + " " + result[2] + " " +
                           result[3] + " " + result[4] + " " + result[5] + " " + result[6]);
    }

    private static void matchPrivateIp(String[] ip, int[] result) {
        if (Integer.parseInt(ip[0]) == 10) {
            result[6] = result[6] + 1;
        }
        if (Integer.parseInt(ip[0]) == 172 && (Integer.parseInt(ip[1]) >= 16 &&
                                               Integer.parseInt(ip[1]) <= 31)) {
            result[6] = result[6] + 1;
        }
        if (Integer.parseInt(ip[0]) == 192 && Integer.parseInt(ip[1]) == 168) {
            result[6] = result[6] + 1;
        }
    }

    private static void matchABCDE(String[] ip, int[] result) {
        if (Integer.parseInt(ip[0]) >= 1 && Integer.parseInt(ip[0]) <= 126) {
            result[0] = result[0] + 1;
        }
        if (Integer.parseInt(ip[0]) >= 128 && Integer.parseInt(ip[0]) <= 191) {
            result[1] = result[1] + 1;
        }
        if (Integer.parseInt(ip[0]) >= 192 && Integer.parseInt(ip[0]) <= 223) {
            result[2] = result[2] + 1;
        }
        if (Integer.parseInt(ip[0]) >= 224 && Integer.parseInt(ip[0]) <= 239) {
            result[3] = result[3] + 1;
        }
        if (Integer.parseInt(ip[0]) >= 240 && Integer.parseInt(ip[0]) <= 255) {
            result[4] = result[4] + 1;
        }
    }

    private static boolean validateNetMask(String[] netmask, int[] result,
                                           int[] rightMask) {
        if (netmask.length != 4) {
            result[5] = result[5] + 1;
            return true;
        }
        int i0 = Integer.parseInt(netmask[0]);
        int i1 = Integer.parseInt(netmask[1]);
        int i2 = Integer.parseInt(netmask[2]);
        int i3 = Integer.parseInt(netmask[3]);
        //排除都是0
        if (i0 == 0 && i1 == 0 && i2 == 0 && i3 == 0) {
            result[5] = result[5] + 1;
            return true;
        }
        //排除都是255
        if (i0 == 255 && i1 == 255 && i2 == 255 && i3 == 255) {
            result[5] = result[5] + 1;
            return true;
        }
        if (Integer.parseInt(netmask[0]) == 255) {
            if (Integer.parseInt(netmask[1]) == 255) {
                if (Integer.parseInt(netmask[2]) == 255) {
                    if (Integer.parseInt(netmask[3]) == 255) {
                    } else {
                        if (checkNetMask(netmask[3], rightMask)) {
                            result[5] = result[5] + 1;
                            return true;
                        }
                    }
                } else {
                    if (checkNetMask(netmask[2], rightMask)) {
                        result[5] = result[5] + 1;
                        return true;
                    } else {
                        if (i3 == 0) {
                        } else {
                            result[5] = result[5] + 1;
                            return true;
                        }
                    }
                }
            } else {
                if (checkNetMask(netmask[1], rightMask)) {
                    result[5] = result[5] + 1;
                    return true;
                } else {
                    if (i2 == 0 && i3 == 0) {
                    } else {
                        result[5] = result[5] + 1;
                        return true;
                    }
                }
            }
        } else {
            if (checkNetMask(netmask[0], rightMask)) {
                result[5] = result[5] + 1;
                return true;
            } else {
                if (i1 == 0 && i2 == 0 && i3 == 0) {
                } else {
                    result[5] = result[5] + 1;
                    return true;
                }
            }
        }
        return false;
    }

    private static boolean checkNetMask(String s, int[] rightMask) {
        int count = 0;
        for (int i = 0; i < rightMask.length; i++) {
            if (rightMask[i] == Integer.parseInt(s)) {
                count = count + 1;
            }
        }
        if (count == 0) {
            return true;
        }
        return false;
    }

    private static boolean validateIp(String[] ip, int[] result) {
        if (ip.length != 4) {
            result[5] = result[5] + 1;
            return true;
        } else {
            int i0 = Integer.parseInt(ip[0]);
            int i1 = Integer.parseInt(ip[1]);
            int i2 = Integer.parseInt(ip[2]);
            int i3 = Integer.parseInt(ip[3]);
            if (i0 < 0 || i0 > 255 || i1 < 0 || i1 > 255 || i2 < 0 || i2 > 255 || i3 < 0 ||
                    i3 > 255) {
                result[5] = result[5] + 1;
                return true;
            }
        }
        return false;
    }

    private static boolean checkPrivate(String[] ip) {
        if (Integer.parseInt(ip[0]) == 0 || Integer.parseInt(ip[0]) == 127) {
            return true;
        }
        return false;
    }
}


发表于 2024-07-18 16:46:26 回复(0)
放一个极其智障的方法在这里。。。这下真的面向答案编程了
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        nextLine:
        while (in.hasNextLine()) {
            String s = in.nextLine();
            String[] IP = s.split("~");
            if (IP.length != 2) {
                break nextLine;
            }
            // only 3 points
            if (IP[0].matches(IPRegexLevel1) && IP[1].matches(IPRegexLevel1)) {
                // IP
                String[] ipNumberString = IP[0].split("\\.");
                if (ipNumberString.length != 4) {
                    Wrong++;
                    continue nextLine;
                }
                int[] ipNumber = new int[4];
                for (int i = 0; i < 4; i++) {
                    ipNumber[i] = Integer.parseInt(ipNumberString[i]);
                    if (ipNumber[i] < 0 || ipNumber[i] > 255) {
                        Wrong++;
                        continue nextLine;
                    }
                }
                if (ipNumber[0] == 0 || ipNumber[0] == 127) {
                    continue nextLine;
                }
                // Invalid Mask
                String[] maskNumberString = IP[1].split("\\.");
                if (maskNumberString.length != 4) {
                    Wrong++;
                    continue nextLine;
                }
                int[] maskNumber = new int[4];
                for (int i = 0; i < 4; i++) {
                    maskNumber[i] = Integer.parseInt(maskNumberString[i]);
                    if (maskNumber[i] < 0 || maskNumber[i] > 255) {
                        Wrong++;
                        continue nextLine;
                    }
                }
                if (maskNumber[0] == 0 || maskNumber[3] == 255) {
                    Wrong++;
                    continue nextLine;
                }
                for (int i = 0; i < 3; i++) {
                    if(maskNumber[i] != 255) {
                        for (int j = i+1; j < 4; j++) {
                            if(maskNumber[j] != 0) {
                                Wrong++;
                                continue nextLine;
                            }
                        }
                    }
                }
                for (int i = 0; i < 4; i++) {
                    if(maskNumber[i] != 255) {
                        if (maskNumber[i] > 0 && maskNumber[i] < 255) {
                            String maskBinary = Integer.toBinaryString(maskNumber[i]);
                            if (maskBinary.length() < 8) {
                                StringBuilder sb = new StringBuilder();
                                for (int j = 0; j < 8 - maskBinary.length(); j++) {
                                    sb.append("0");
                                }
                                sb.append(maskBinary);
                                maskBinary = sb.toString();
//                                maskBinary = "0".repeat(8 - maskBinary.length()) + maskBinary;
                            }
                            boolean validMask = maskBinary.matches("^1{0,32}0{0,32}$");
                            if (!validMask) {
                                Wrong++;
                                continue nextLine;
                            }
                        }

                    }
                }

                // IP
                // A
                if (ipNumber[0]>0 && ipNumber[0] < 127) {
                    A++;
                }
                // B
                if (ipNumber[0] > 127 && ipNumber[0] < 192) {
                    B++;
                }
                // C
                if (ipNumber[0] >= 192 && ipNumber[0] <= 223){
                    C++;
                }
                // D
                if (ipNumber[0] >= 224 && ipNumber[0] <= 239) {
                    D++;
                }
                // E
                if (ipNumber[0] >= 240 && ipNumber[0] <= 255) {
                    E++;
                }
                // Private
                if (ipNumber[0] == 10 || (ipNumber[0] == 172 && ipNumber[1] >= 16 && ipNumber[1] <= 31) || (ipNumber[0] == 192 && ipNumber[1] == 168)) {
                    Private++;
                }

            } else {
                Wrong++;
                continue nextLine;
            }
        }
        System.out.println(A+" "+B+" "+C+" "+D+" "+E+" "+Wrong+" " + Private);
    }

    static int A=0,B=0,C=0,D=0,E=0,Wrong=0,Private=0;
    public static final String IPRegexLevel1 = "^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$";
}


发表于 2024-06-13 23:52:55 回复(0)
卡在60%,期望输出71 41 21 12 10 68 1,实际输出73 41 21 13 10 65 1。琢磨一中午没想明白,看半天讨论区才知道问题在哪。

里面有个测试案例的子网掩码是255.16.0.0
我以为的:255→11111111;16→111;0→0;0→0,所以转为二进制后是:1111111111100,一连串的1后跟一连串的0,符合规则
实际上的:255→11111111;16→00000111;0→00000000;0→00000000,所以转为二进制后是11111111000001110000000000000000,不符合规则。

所以要在String.toBinaryString的时候,加一个leftPad就行了
发表于 2024-06-13 18:30:12 回复(3)
import java.util.Arrays;
import java.util.Scanner;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {

    // 过滤掉0.* 127.*的地址
    // 优先匹配私网ip
    // 再匹配ABCDE类地址
    // 子网掩码匹配,必须以1起始,并且全0或全1是非法的。
    static int[] result = new int[7];

    static long aLeft = 0x01000000L, aRight = 0x7effffffL;
    static long bLeft = 0x80000000L, bRight = 0xbfffffffL;
    static long cLeft = 0xc0000000L, cRight = 0xdfffffffL;
    static long dLeft = 0xe0000000L, dRight = 0xefffffffL;
    static long eLeft = 0xf0000000L, eRight = 0xffffffffL;

    static long apl = 0x0a000000L, apr = 0x0affffffL;
    static long bpl = 0xac100000L, bpr = 0xac31ffffL;
    static long cpl = 0xc0a80000L, cpr = 0xc0a8ffffL;

    public static long ip2Dec(String ip) {
        String[] ipPoint = ip.split("\\.");
        if (ipPoint.length != 4) return -1;
        long sum = 0;
        for (int i = 24, j = 0; j < 4; ++j, i -= 8) {
            long a = Integer.parseInt(ipPoint[j]);
            sum += a << i;
        }
        return sum;
    }

    public static boolean isIpValid(String ip) {
        long ipDec = ip2Dec(ip);
        return ipDec >= aLeft && ipDec <= eRight;
    }

    public static boolean isMarkValid(String mark) {
        String[] ms = mark.split("\\.");
        if (ms.length != 4 || ms[3].equals("255") || ms[0].equals("0")) return false; 
        String b = "";
        for (String t : ms) {
            b += String.format("%08d", Integer.parseInt(Integer.toBinaryString(Integer.parseInt(t))));
        }
        boolean findZero = false;
        for (int i = 0; i < b.length(); ++ i) {
            if (b.charAt(i) == '0') findZero = true;
            if (findZero && b.charAt(i) == '1') return false;
        }
        return true;
    }

    public static boolean isPrivate(String ip) {
        long a = ip2Dec(ip);
        return (a >= apl && a <= apr) || (a >= bpl && a <= bpr) || (a >= cpl && a <= cpr);
    }

    public static void group(String ip) {
        long a = ip2Dec(ip);
        if (a >= aLeft && a <= aRight) result[0] ++;
        if (a >= bLeft && a <= bRight) result[1] ++;
        if (a >= cLeft && a <= cRight) result[2] ++;
        if (a >= dLeft && a <= dRight) result[3] ++;
        if (a >= eLeft && a <= eRight) result[4] ++;
    }

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNextLine()) {
            String ipAndMark = in.nextLine();
            String[] arr = ipAndMark.split("~");
            if (arr[0].startsWith("0.") || arr[0].startsWith("127.")) continue;
            if (!isIpValid(arr[0]) || !isMarkValid(arr[1])) {
                result[5] ++;
            }else {
                if (isPrivate(arr[0])) {
                    result[6] ++;
                }
                group(arr[0]);
            }
        }
        for (int r : result) System.out.print(r + " "); 
    }
}

发表于 2024-03-20 12:02:36 回复(0)

这个用例是错的吧,非法掩码怎么数都是14个,就是我红线拉掉的那些,答案是13个,到底多了哪一个?
编辑于 2024-03-16 20:39:01 回复(5)
取巧的解法。不过中途被题目坑了,先感谢下《牛客62664608号》的提示,子网掩码在做进制转换的时候需要补位,不足8位的要在前面补0。例如:1的二进制是:1,要在前面补足七个零补成:00000001。题目真坑;
import java.util.Scanner;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        int A = 0, B = 0, C = 0, D = 0, E = 0, err = 0, pr = 0;

        while (in.hasNext()) {
            String val = in.nextLine();
            //ip和子网掩码拆分
            String[] vals = val .split("~");
            //ip
            String[] ips = vals[0].split("\\.");
            //子网
            String[] subnets = vals[1].split("\\.");
            //校验无效值
            if (ips[0].equals("0") || ips[0].equals("127")) {
                continue;
            }
            //校验ip和子网掩码是否为空
            if (!checkErr(ips) || !checkErr(subnets) ) {
                err = err + 1;
                continue;
            }

            //类型转换
            //ip
            Integer[] ipis = new Integer[4];
            //子网
            Integer[] subnetis = new Integer[4];
            for (int i = 0 ; i < 4 ; i ++) {
                ipis[i] = Integer.parseInt(ips[i]);
                subnetis[i] = Integer.parseInt(subnets[i]);
                if (ipis[i] > 255 || subnetis[i] > 255) {
                    System.out.println(val);
                }
            }

            //校验错误的子网掩码
            if (!checkSubnet(subnetis)) {
                err = err + 1;
                continue;
            }
            //校验ip类型
            if (ipis[0] >= 1 && ipis[0] <= 126 ) {
                A = A + 1;
            } else if (ipis[0] >= 128 && ipis[0] <= 191 ) {
                B = B + 1;
            } else if (ipis[0] >= 192 && ipis[0] <= 223 ) {
                C = C + 1;
            } else if (ipis[0] >= 224 && ipis[0] <= 239 ) {
                D = D + 1;
            } else if (ipis[0] >= 240 && ipis[0] <= 255 ) {
                E = E + 1;
            }

            //校验是否是私网ip
            if (ipis[0] == 10) {
                pr = pr + 1;
            }
            if (ipis[0].equals(172) && ipis[1] >= 16  && ipis[1] <= 31) {
                pr = pr + 1;
            }
            if (ipis[0].equals(192) && ipis[1].equals(168)) {
                pr = pr + 1;
            }
        }

        System.out.print(A + " " + B + " " + C + " " + D + " " + E + " " + err + " " +
                         pr);
    }
    //校验是否存在空值
    public static boolean checkErr(String[] val) {
        for (String i : val) {
            if (i == null || i.length() < 1) {
                return false;
            }
        }
        return true;
    }

    //校验子网掩码是否合法
    public static boolean checkSubnet(Integer[] vals) {
        if (vals[0].equals(0) || vals[3].equals(255)) {
            return false;
        }
        //true 为1,false为0
        Boolean flag = true;
        for (Integer i : vals) {
            StringBuilder val = new StringBuilder(Integer.toBinaryString(i));
            if (val.length() < 8) {
                for (int z = 0; z < 8 - val.length(); z++) {
                    val.insert(0,0);
                }
            }
            int[] ss = val.chars().toArray();
            for (Integer s : ss) {
                if (flag && s.equals(48)) {
                    flag = false;
                } else if (!flag && s.equals(49)) {
                    return false;
                }
            }
        }
        return true;
    }
}


发表于 2024-03-15 15:54:07 回复(0)
判断子网掩码是否有误的时候,除了题目给的限制要求,其实还暗含着另一个要求,就是子网掩码不能为255.255.255.255(不能全为1
编辑于 2024-03-15 11:38:05 回复(0)
用正则

import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    static String one2OneTwoSix = "([1-9]|[1-9][0-9]|1[01][0-9]|12[0-6])";
    static String zero2TwoFiveFive =
        "([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])";
    static String oneTwoEight2OneNightOne = "(1(2[89]|[3-8][0-9]|9[01]))";
    static String oneNightTwo2TwoTwoThree = "(19[2-9]|2[01][0-9]|22[0-3])";
    static String twoTwoFour2TwoThreeNight = "(22[4-9]|23[0-9])";
    static String twoFourZero2twoFiveFive = "(24[0-9]|25[0-5])";
    static String oneSix2ThreeOne = "(1[6-9]|2[0-9]|3[01])";
    static String A = "(" + one2OneTwoSix + ")(\\." + zero2TwoFiveFive + "){3}";
    static String B = "(" + oneTwoEight2OneNightOne + ")(\\." + zero2TwoFiveFive +
                      "){3}";
    static String C = "(" + oneNightTwo2TwoTwoThree + ")(\\." + zero2TwoFiveFive +
                      "){3}";
    static String D = "(" + twoTwoFour2TwoThreeNight + ")(\\." + zero2TwoFiveFive +
                      "){3}";
    static String E = "(" + twoFourZero2twoFiveFive + ")(\\." + zero2TwoFiveFive +
                      "){3}";
    static String PRIVATE =
        "10(\\." + zero2TwoFiveFive + "){3}|"
        + "172\\.(" + oneSix2ThreeOne + ")(\\." + zero2TwoFiveFive + "){2}|" +
        "192\\.168(\\." + zero2TwoFiveFive + "){2}";
    static String RIGHT = "(" + zero2TwoFiveFive + ")(\\." + zero2TwoFiveFive +
                          "){3}";
    static String one = "0|128|192|224|240|248|252|254";
    static String MASK =
        "(" + one + ")(\\.0){3}|" +
        "255\\.(" + one + ")(\\.0){2}|" +
        "(255\\.){2}(" + one + ")\\.0|" +
        "(255\\.){3}(" + one + ")";

    static Pattern patternMask = Pattern.compile(MASK);
    static String OTHER = "(0|127)(\\.\\d*){3}";
    static Pattern patternOther = Pattern.compile(OTHER);

    static Pattern[] patterns = {Pattern.compile(A), Pattern.compile(B), Pattern.compile(C), Pattern.compile(D), Pattern.compile(E), null, Pattern.compile(PRIVATE)};
    static Pattern patternRight = Pattern.compile(RIGHT);

    public static void main(String[] args) {
        int[] count = new int[7];
        Scanner in = new Scanner(System.in);

        while (in.hasNextLine()) {
            String line = in.nextLine();
            count(line, count);
        }
        for (int i : count) {
            System.out.print(i + " ");
        }
    }
    private static void count(String s, int[] count) {
        String[] split = s.split("~");
        String ip = split[0];
        String mask = split[1];
        Matcher matcherOther = patternOther.matcher(ip);
        if (matcherOther.matches()) {
            return;
        }
        Matcher matcherIp = patternRight.matcher(ip);
        Matcher matcherMask = patternMask.matcher(mask);
        if (!matcherIp.matches() || !matcherMask.matches()) {
            count[5]++;
            return;
        }
        for (int i = 0; i < patterns.length; i++) {
            Pattern pattern = patterns[i];
            if (pattern == null) {
                continue;
            }
            if (pattern.matcher(ip).matches()) {
                count[i]++;
            }
        }

    }

 }


发表于 2024-03-13 17:30:18 回复(0)
0.201.56.50~255.255.111.255
127.201.56.50~255.255.111.255
这个为什么是0 0 0 0 0 0 0 而不是0 0 0 0 0 2 0 
发表于 2024-02-01 10:07:29 回复(1)
将ip地址或掩码转换为整数,然后使用移位操作进行判断
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        int aCnt = 0, bCnt = 0, cCnt = 0, dCnt = 0, eCnt = 0, errCnt = 0, privateCnt = 0;
        while (in.hasNextLine()) { // 注意 while 处理多个 case'
            String inputLine = in.nextLine();
            if (inputLine.isEmpty()) break;
            //处理读入的ip地址
            String[] items = inputLine.split("~");
            String ip = items[0];
            String mask = items[1];
            //跳过不属于任何类型的ip
            if (isFmtValid(ip) && (ip.startsWith("0.") || ip.startsWith("127."))) continue;
            if (!isMaskValid(mask) || !isIpValid(ip)) {
                errCnt++;
                continue;
            }
            //判断ip的类型
            Long ipLongVal = getIpLongVal(ip);
            if ((ipLongVal >= getIpLongVal("10.0.0.0") && ipLongVal <= getIpLongVal("10.255.255.255")) ||
                (ipLongVal >= getIpLongVal("172.16.0.0") && ipLongVal <= getIpLongVal("172.31.255.255")) ||
                (ipLongVal >= getIpLongVal("192.168.0.0") && ipLongVal <= getIpLongVal("192.168.255.255"))) {
                privateCnt++;
            }
            if ((ipLongVal >= getIpLongVal("1.0.0.0") && ipLongVal <= getIpLongVal("126.255.255.255"))) {
                aCnt++;
            } else if ((ipLongVal >= getIpLongVal("128.0.0.0") && ipLongVal <= getIpLongVal("191.255.255.255"))) {
                bCnt++;
            } else if ((ipLongVal >= getIpLongVal("192.0.0.0") && ipLongVal <= getIpLongVal("223.255.255.255"))) {
                cCnt++;
            } else if ((ipLongVal >= getIpLongVal("224.0.0.0") && ipLongVal <= getIpLongVal("239.255.255.255"))) {
                dCnt++;
            } else if ((ipLongVal >= getIpLongVal("240.0.0.0") && ipLongVal <= getIpLongVal("255.255.255.255"))) {
                eCnt++;
            }
        }
        System.out.println(aCnt + " " + bCnt + " " + cCnt + " " + dCnt + " " + eCnt + " " + errCnt + " " + privateCnt);
    }
    public static boolean isIpValid(String ip) {
        //格式非法
        return isFmtValid(ip);
    }

    public static Long getIpLongVal(String ip) {
        String[] ipItems = ip.split("\\.");
        Long ipLongVal = 0L;
        for (int i = 0; i < ipItems.length; i++) {
            Long posVal = Long.valueOf(ipItems[i]);
            //计算得到掩码的10进制值
            ipLongVal += (posVal << 8 * (3 - i));
        }
        return ipLongVal;
    }

    //判断ip或掩码格式是否合法
    public static boolean isFmtValid(String ip) {
        String[] ipItems = ip.split("\\.");
        if (ipItems.length != 4) {
            return false;
        } else {
            for (int i = 0; i < ipItems.length; i++) {
                if (!isInteger(ipItems[i]) ||
                        Integer.valueOf(ipItems[i]) > 255 ||
                        Integer.valueOf(ipItems[i]) < 0) {
                    return false;
                }
            }
        }
        return true;
    }

    public static boolean isMaskValid(String mask) {
        //格式非法
        if (!isFmtValid(mask)) return false;
        //格式合法,判断掩码是否合法
        String[] maskItems = mask.split("\\.");
        Long maskVal = getIpLongVal(mask);
        //全0或全1的情况非法
        if (maskVal == 0L || maskVal == ((1L << 32) - 1)) {
            return false;
        }
        maskVal = maskVal << 32;//将计算得到的掩码移到高32位
        if (maskVal > 0) return false;
        //左移32次,如果出现大于0的数,则非法
        for (int i = 0; i < 32; i++) {
            maskVal = maskVal << 1;
            if (maskVal > 0) return false;
        }
        return true;
    }

    public static boolean isInteger(String str) {
        boolean isInt = false;
        try {
            Integer.valueOf(str);
            isInt = true;
        } catch (NumberFormatException e) {
            isInt = false;
        }
        return isInt;
    }
}


发表于 2024-01-29 09:01:36 回复(0)
为什么我这个代码只能通过80%的案例呢。。。。
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
  
        testCheckIp();
    }

    public static void testCheckIp() {
        Scanner in = new Scanner(System.in);
        int aNum = 0;
        int bNum = 0;
        int cNum = 0;
        int dNum = 0;
        int eNum = 0;
        int errNum = 0;
        int pNum = 0;
        List<String> errIp = new ArrayList<>();
      /*
        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
         */
        while (in.hasNextLine()) {
            String ipStr = in.nextLine();
            String[] ipArr = ipStr.split("~");

            int firstIp = getIpSeq(ipArr[0], 0);
            if (firstIp == 0 || firstIp == 127) {
                continue;
            }
            if (ipIsInvalid(ipArr[0])) {
                errNum++;
                errIp.add(ipArr[0]);
                continue;
            }

            if (maskIsInvalid(ipArr[1])) {
                errNum++;
                errIp.add(ipArr[1]);
                continue;
            }

            if (firstIp >= 1 && firstIp <= 126) {
                aNum++;
            }
            if (firstIp >= 128 && firstIp <= 191) {
                bNum++;
            }
            if (firstIp >= 192 && firstIp <= 223) {
                cNum++;
            }
            if (firstIp >= 224 && firstIp <= 239) {
                dNum++;
            }
            if (firstIp >= 240 && firstIp <= 255) {
                eNum++;
            }
            int secIp = getIpSeq(ipArr[0], 1);
            if (firstIp == 10 || (firstIp == 172 && secIp >= 16 && secIp <= 31) || (firstIp == 192 && secIp == 168)) {
                pNum++;
            }


        }
        System.out.println(aNum + " " + bNum + " " + cNum + " " + dNum + " " + eNum + " " + errNum + " " + pNum);
    }

    private static boolean ipIsInvalid(String ip) {
        /**
         * 第一部分:匹配3个0~255.(注意后面的一个点)(重复匹配3次)
         * 第二部分:匹配最后的数字0~255
         */
        String regex = "((1[0-9][0-9]\\.)|(2[0-4][0-9]\\.)|(25[0-5]\\.)|([1-9][0-9]\\.)|([0-9]\\.)){3}((1[0-9][0-9])|(2[0-4][0-9])|(25[0-5])|([1-9][0-9])|([0-9]))";
        return !ip.matches(regex);
    }

    private static boolean maskIsInvalid(String maskIp) {
        String regex = "(255.0.0.0)|(255.255.0.0)|(255.255.255.0)";
        return !maskIp.matches(regex);
    }

    private static int getIpSeq(String ip, int index) {
        String[] ipArr = ip.split("\\.");
        return Integer.parseInt(ipArr[index]);
    }
}


发表于 2023-12-20 21:57:56 回复(0)