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

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

https://www.nowcoder.com/practice/de538edd6f7e4bc3a5689723a7435682

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

 
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
 
    public static int[] ans = new int[7];
 
    public static void main(String[] args) {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        try {
            String line;
            while((line = br.readLine()) != null) {
                try {
                    String[] IPandYanma = line.split("\\~");
                    if(IPandYanma.length != 2) {
                        ans[5]++;
                        continue;
                    }
                    String[] IPparts = IPandYanma[0].split("\\.");
                    String[] Yanmaparts = IPandYanma[1].split("\\.");
                    if(IPparts[0].equals("127")) {
                        continue;
                    }
                    if(!YanmaisIllegal(Yanmaparts)) {
                        ans[5]++;
                        continue;
                    } else {
                        handleOneIP(IPparts, Yanmaparts);
                    }
                } catch (NumberFormatException e) {
                    ans[5]++;
                }
            }
            for(int i = 0; i < ans.length; i++) {
                bw.write(String.valueOf(ans[i]) + " ");
                bw.flush();
            }
        } catch (IOException e) {
 
        }
    }
 
    public static void handleOneIP(String[] IPparts, String[] yanmaParts) {
        if(IPparts.length != 4) {
            ans[5]++;
            return;
        }
        for(int i = 0; i < IPparts.length; i++) {
            String part = IPparts[i];
            if(part.isEmpty()) {
                ans[5]++;
                return;
            }
            // 检查前导零(长度>1且以0开头,如"01")
            if (part.length() > 1 && part.startsWith("0")) {
                ans[5]++;
                return;
            }
            if (part.startsWith("+")) {
                ans[5]++;
                return;
            }
            //判断各个IP部分是否为空
            int Ip = Integer.parseInt(part);
            if(Ip < 0 || Ip > 255) {
                ans[5]++;
                return;
            }
        }

        // 新增:计算IP和掩码的32位二进制
        String ipBinary = "";
        String yanmaBinary = "";
        for (int i = 0; i < 4; i++) {
            ipBinary += turnToString(IPparts[i]); // 复用turnToString获取8位二进制
            yanmaBinary += turnToString(yanmaParts[i]);
        }

        // 提取主机位(掩码为0的部分)
        String hostBits = "";
        for (int i = 0; i < 32; i++) {
            if (yanmaBinary.charAt(i) == '0') { // 掩码0对应主机位
                hostBits += ipBinary.charAt(i);
            }
        }

        // 若主机位全0(网络地址)或全1(广播地址),判定为非法
        if (hostBits.replace("0", "").isEmpty() || hostBits.replace("1", "").isEmpty()) {
            
        }

        String IPhead = IPparts[0];
        int IP = Integer.parseInt(IPhead);
        int IP2 = Integer.parseInt(IPparts[1]);
        int IP3 = Integer.parseInt(IPparts[2]);
        int target;
        if(IP > 0 && IP <= 127) {
            ans[0]++;
        }
        if(IP > 127 && IP <= 191) {
            ans[1]++;
        }
        if(IP > 191 && IP <= 223) {
            ans[2]++;
        }
        if(IP > 223 && IP <= 239) {
            ans[3]++;
        }
        if(IP > 239 && IP <= 255) {
            ans[4]++;
        }
        if(IP == 10 || (IP == 172 && IP2 >=16 && IP2 < 32) || (IP == 192 && IP2 == 168)) {
            ans[6]++;
        }
    }
 
    //判断掩码部分是否合法
    public static boolean YanmaisIllegal(String[] input) {
        int n = input.length;
        if(n != 4) {
            return false;
        }
        StringBuffer sb = new StringBuffer();
        //判断是否全为1或全为0
        for (int i = 0; i < n; i++) {
            if (input[i].isEmpty()) {
                return false;
            }
            if (Integer.parseInt(input[i]) < 0 || Integer.parseInt(input[i]) > 255) {
                return false;
            }
            sb.append(input[i]);
        }
        if(sb.toString().equals("255255255255") || sb.toString().equals("0000")) {
            return false;
        }
        boolean haveZero = false;
        //判断每一部分是否合法
        for (int i = 0; i < n; i++) {
            int index = 0;
            String part = input[i];
            if(part.length() > 1 && part.startsWith("0")) {
                return false;
            }
            if(haveZero && !part.equals("0")) {
                return false;
            }
            part = turnToString(part);
            char now = part.charAt(0);
            for (int j = 1; j < part.length(); j++) {
                char last = part.charAt(j);
                //好像只需要考虑前一个是0,后一个是1的情况是异常,其余比如00,11,10都是正常的,因为已经排除了极端情况
                //事实证明不是这样,在前三个的时候都要标记是否出现了0,如果已经出现了0,后续都不能再出现1
                if(now == '0' || last == '0') {
                    haveZero = true;
                    if(last == '0') {
                        continue;
                    } else {
                        return false;
                    }
                }
                if(last == '1' && haveZero) {
                    return false;
                }
                now = last;
            }
        }
        return true;
    }
 
     
    //这个函数将掩码的单个部分转化为八位二进制字符串
    public static String turnToString(String part) {
        int num = Integer.parseInt(part);
        return String.format("%8s", Integer.toBinaryString(num)).replace(' ', '0');
    }
 
}

全部评论

相关推荐

2025-12-18 12:37
南京邮电大学 C++
牛客87317764...:然后客户端边学边投,学个1个月投不进去都是正常的,这玩意非常看运气
投递快手等公司9个岗位
点赞 评论 收藏
分享
2025-12-04 15:23
三峡大学 FPGA工程师
不知道怎么取名字_:玩游戏都写到简历上了啊
投递BOSS直聘等公司9个岗位
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务