题解 | IP 分类:使用IntPredicate函数方法

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

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

import java.math.*;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.*;
import java.util.stream.*;
import java.util.regex.*;
import java.util.function.*;
import java.net.*;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int countA = 0, countB = 0, countC = 0, countD = 0, countE = 0,
            countError = 0, countPrivate = 0;

        while (in.hasNextLine()) {
            String line = in.nextLine();
            String ip = line.split("~")[0];
            String mask = line.split("~")[1];

            if (shouldSkip(ip)) {
                continue;
            }

            if (!isIpIleagl(ip) || !isMaskIleagl(mask)) {
                countError++;
            } else {
                countA = isIpRange(ip, n->(n >= 1 && n <= 126)) ? countA + 1 : countA;
                countB = isIpRange(ip, n->(n >= 128 && n <= 191)) ? countB + 1 : countB;
                countC = isIpRange(ip, n->(n >= 192 && n <= 223)) ? countC + 1 : countC;
                countD = isIpRange(ip, n->(n >= 224 && n <= 239)) ? countD + 1 : countD;
                countE = isIpRange(ip, n->(n >= 240 && n <= 255)) ? countE + 1 : countE;
                countPrivate = isIpPrivate(ip) ? countPrivate + 1 : countPrivate;
            }

        }

        System.out.printf("%d %d %d %d %d %d %d\n"
                          , countA, countB, countC, countD, countE, countError, countPrivate);
    }

    static boolean isIpIleagl(String ip) {
        try {
            InetAddress address = InetAddress.getByName(ip);
            return address.getHostAddress().equals(ip);
        } catch (UnknownHostException e) {
            return false;
        }
    }

    static boolean isMaskIleagl(String mask) {
        if (!isIpIleagl(mask)) {
            return false;
        }

        // transfer to 0 1
        String[] nums = mask.split("\\.");
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 4; i++) {
            String bStr = Integer.toBinaryString(Integer.parseInt(nums[i]));
            bStr = Collections.nCopies(8 - bStr.length(), "0")
                   .stream().collect(Collectors.joining("")) + bStr;
            sb.append(bStr);
        }

        boolean has0 = false;
        for (int i = 0; i < sb.length(); i++) {
            if (has0 && '1' == sb.charAt(i)) {
                return false;
            }
            if ('0' == sb.charAt(i)) {
                has0 = true;
            }
        }
        if (!has0) {
            return false;
        }
        if (sb.charAt(0) == '0') {
            return false;
        }
        return true;
    }

    static boolean isIpRange(String ip, IntPredicate p) {
        if (!isIpIleagl(ip)) return false;

        int first = Integer.parseInt(ip.split("\\.")[0]);
        return p.test(first);
    }
    static boolean isIpPrivate(String ip) {
        if (!isIpIleagl(ip)) return false;

        int first = Integer.parseInt(ip.split("\\.")[0]);
        int second = Integer.parseInt(ip.split("\\.")[1]);

        return (first == 10)
               || (first == 172 && (second >= 16 && second <= 31))
               || (first == 192 && second == 168);
    }

    static boolean shouldSkip(String ip) {
        if (!isIpIleagl(ip)) return false;
        int first = Integer.parseInt(ip.split("\\.")[0]);
        return first == 0 || first == 127;
    }
}


全部评论

相关推荐

AAA专业长城贴瓷砖刘大爷:这样的简历我会直接丢进垃圾桶,花里胡哨的
点赞 评论 收藏
分享
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务