题解 | #字符串最后一个单词的长度#

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

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

Java ip转32二进制 + 正则表达式

刚复习完正则表达式,突然兴起练练手

  • 如果直接用匹配点分十进制,RegularExpression会很臃肿

    regexIP = "^(2(5[0-5]|[0-4]\d)|[0-1]?\d{1,2})(\.(2(5[0-5]|[0-4]\d)|[0-1]?\d{1,2})){3}$"

    于是考虑转为32位二进制再匹配会方便一些

    // 将 *.*.*.* 点分十进制字符串转为 32 位二进制
    static String ipToBinary(String ip) {
      StringBuilder sb = new StringBuilder();
      for (String s : ip.split("\\.")) {
          int n = Integer.parseInt(s);
          if (n > 255) {
              return "";
          } else {
              // 左移8位再或运算,得到9位,取后8位
              sb.append(Integer.toBinaryString(1 << 8 | n).substring(1));
          }
      }
      return sb.toString();
    }
  • 然后结合计网的知识写正则表达式,只需要用最基础的正则表达式语法即可

    ^:匹配开头
    $:匹配结尾
    ?:匹配0个或1个
    *:0个或多个
    +:1个或多个
    [0-1]:范围内任意一个值
    \d:即[0-9]
    {n}:"E{n}"匹配n个E,"E{m,n}"匹配m~n个E,前闭后闭
    // 注意java中 \ 要转义,写 \\d
  • 完整代码

import java.util.Scanner;

public class Main {
    // 正则表达式
    static String likeIP = "^\\d{1,3}(\\.\\d{1,3}){3}$",  // 匹配点分十进制 *.*.*.*
            regMask = "^1+0+$",  // 匹配掩码
            regZ = "^0{8}[0-1]{24}$",  // 匹配 0.*.*.*
            regL = "^01{7}[0-1]{24}$",  // 匹配 127.*.*.*
            regA = "^0[0-1]{31}$",  // include 0.*.*.* & 127.*.*.*
            regApriv = "^00001010[0-1]{24}$",  // 匹配A类私有ip
            regB = "^10[0-1]{30}$",
            regBpriv = "^101011000001[0-1]{20}$",
            regC = "^110[0-1]{29}$",
            regCpriv = "^1100000010101000[0-1]{16}$",
            regD = "^1110[0-1]{28}$",
            regE = "^1111[0-1]{28}$";

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int A = 0, B = 0, C = 0, D = 0, E = 0, ERR = 0, PRIV = 0;
        while (sc.hasNext()) {
            String[] input = sc.next().split("~");
            if (input.length == 0) {
                break;
            }
            String ip = input[0];
            String mask = input[1];
//             System.out.println(ip + "   " + mask);
            // 验证掩码
            if (mask.matches(likeIP)) {
                if (!ipToBinary(mask).matches(regMask)) {
                    ERR++;
//                     System.out.println("error mask");
                    continue;  // 掩码错误,跳过
                }
            }
            // 验证ip
            if (ip.matches(likeIP)) {
                String ipStr = ipToBinary(ip);
//                 System.out.println(ipStr);
                if (ipStr.matches(regZ) || ipStr.matches(regL)) {
                    // 0.*.*.* 和 127.*.*.* 不做处理
                } else {
                    if (ipStr.matches(regA)) {
                        A++;
//                         System.out.println(ip + " is a A ip");
                        if (ipStr.matches(regApriv)) {
                            PRIV++;
                        }
                    } else if (ipStr.matches(regB)) {
                        B++;
//                         System.out.println(ip + " is a B ip");
                        if (ipStr.matches(regBpriv)) {
                            PRIV++;
                        }
                    } else if (ipStr.matches(regC)) {
                        C++;
//                         System.out.println(ip + " is a C ip");
                        if (ipStr.matches(regCpriv)) {
                            PRIV++;
                        }
                    } else if (ipStr.matches(regD)) {
                        D++;
//                         System.out.println(ip + " is a D ip");
                    } else if (ipStr.matches(regE)) {
                        E++;
//                         System.out.println(ip + " is a E ip");
                    }
                }
            } else {
                ERR++;
            }
        }
        System.out.println(A+" "+B+" "+C+" "+D+" "+E+" "+ERR+" "+PRIV);
    }

    // 将 *.*.*.* 点分十进制字符串转为 32 位二进制
    static String ipToBinary(String ip) {
        StringBuilder sb = new StringBuilder();
        for (String s : ip.split("\\.")) {
            int n = Integer.parseInt(s);
            if (n > 255) {
                return "";
            } else {
                sb.append(Integer.toBinaryString(1 << 8 | n).substring(1));  // 左移8位再或运算,得到9位,取后8位
            }
        }
        return sb.toString();
    }
}
全部评论

相关推荐

联通 技术人员 总包不低于12
点赞 评论 收藏
分享
头像
10-22 19:18
上海大学 后端
jopajhhdjwnqk:水印都叠杀人书了
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务