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

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

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

注释比较全,看注释就行

import java.util.Scanner;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 记录所有的错误数
        int[] count = new int[7];
        // 注意 hasNext 和 hasNextLine 的区别
        while (in.hasNextLine()) { // 注意 while 处理多个 case
            String[] s = in.nextLine().split("~");
            String[] ips = s[0].split("\\.");
            // 类似于【0.*.*.*】和【127.*.*.*】的IP地址不属于上述输入的任意一类
            if ("0".equals(ips[0]) || "127".equals(ips[0])) {
                continue;
            }
            if (dnsIsOk(s[1]) && ipIsOK(s[0])) {
                // 开始判断
                int ip1 = Integer.parseInt(ips[0]);
                int ip2 = Integer.parseInt(ips[1]);
                if (ip1 >= 1 && ip1 <= 126) {
                    count[0]++;
                } else if (ip1 >= 128 && ip1 <= 191) {
                    count[1]++;
                } else if (ip1 >= 192 && ip1 <= 223) {
                    count[2]++;
                } else if (ip1 >= 224 && ip1 <= 239) {
                    count[3]++;
                } else if (ip1 >= 240 && ip1 <= 255) {
                    count[4]++;
                }
                // 私有IP地址和A,B,C,D,E类地址是不冲突的 这里不能接上面的 else if
                if (ip1 == 10) {
                    count[6]++;
                }
                if (ip1 == 172 && ip2 >= 16 && ip2 <= 31) {
                    count[6]++;
                }
                if (ip1 == 192 && ip2 == 168) {
                    count[6]++;
                }
            } else {
                // 错误子网掩码或 IP
                count[5]++;
            }
        }
        
        System.out.println(count[0] + " " + count[1] + " " + count[2] + " " + count[3] + " " + count[4] + " " + count[5] + " " + count[6]);
    }
    
    // 是否是合法 IP
    public static boolean ipIsOK(String s) {
        boolean flag = true;
        String[] ips = s.split("\\.");
        if (ips.length == 4) {
            for (int i = 0; i < 4; i++) {
                String ss = ips[i].trim();
                if (ss.isEmpty()) {
                    flag = false;
                    break;
                }
                int j = Integer.parseInt(ss);
                if (ss.length() > 3) {
                    flag = false;
                    break;
                } else if (!"0".equals(ss) && ss.charAt(0) == '0') {
                    flag = false;
                    break;
                } else if (j < 0 || j > 255) {
                    flag = false;
                    break;
                }
            }
        } else {
            flag = false;
        }
        
        return flag;
    }
    
    // 判断子网掩码是否合法
    // 将子网掩码转换为 32 为二进制,看第一个 0 的索引和最后一个 1 的索引是否的大小关系
    public static boolean dnsIsOk(String s) {
        boolean flag = true;
        String[] dns = s.split("\\.");
        if (dns.length == 4) {
            for (int i = 0; i < 4; i++) {
                String ss = dns[i].trim();
                if (ss.length() == 0) {
                    flag = false;
                    break;
                } 
                int j = Integer.parseInt(ss);
                if (ss.length() > 3) {
                    flag = false;
                    break;
                } else if (j < 0 || j > 255) {
                    flag = false;
                    break;
                }
            }
        } else {
            flag = false;
        }
        
        // 只有 flag 为 true,才表名 掩码没有格式上的问题,这时候再判断是否是1在前0在后
        if (flag) {
            StringBuilder builder = new StringBuilder();
            for (int i = 0; i < dns.length; i++) {
                String ss = Integer.toString(Integer.valueOf(dns[i]), 2);
                ss = "00000000" + ss;
                builder.append(ss.substring(ss.length() - 8));
            }
            
            String ret = builder.toString();
            //最后一个1在第一个0之前,有效,否则无效(注意二进制下全是1或者全是0均为非法子网掩码)这里全 1 或全 0 也是 false
            flag = ret.indexOf("0") > ret.lastIndexOf("1");
        }
        
        return flag;
    }
    
    
    
    
    
    
    
    
    
}
全部评论

相关推荐

阿武同学:基本信息保留前面三行,其他的可以全部删掉,邮箱最重要的你没写,主修课程精简到8个以内,实习里面2/3/4都是水内容的,非要写的话建议两到三句话,项目经历排版优化下,自我评价缩到三行
点赞 评论 收藏
分享
迷茫的大四🐶:好一个误闯天家,我也想闯一闯
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

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