CIDR合并---(80分)

package cccf;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 描述:代码注释以及格式化示例
 * 创建人:@author Songguanye
 * 创建时间:2019/3/28 9:42
 * 修改理由:
 * 修改内容:
 */
public class CIDRMerge {
    private String ip;
    private int len;
    private String binaryIp;

    private String getBinaryIp() {
        return binaryIp;
    }

    private void setBinaryIp(String binaryIp) {
        this.binaryIp=binaryIp;
    }

    private String getIp() {
        return ip;
    }

    private void setIp(String ip) {
        this.ip=ip;
    }

    private int getLen() {
        return len;
    }

    private void setLen(int len) {
        this.len=len;
    }
    private static List<CIDRMerge> handleIncompleteIpPrefix(String[] ipPrefixArray){
        List<CIDRMerge> cIDRMergeList = new ArrayList<>();
        for (String anIpPrefixArray : ipPrefixArray) {
            CIDRMerge cidrMerge=new CIDRMerge();
            StringBuilder binaryString=new StringBuilder();
            if (anIpPrefixArray.contains("/")) {
                //标准型或者省略后缀型
                String[] tempArray=anIpPrefixArray.split("/");
                String[] tempArray2=tempArray[0].split("\\.");
                if (tempArray2.length - 1 == 2) {
                    cidrMerge.setIp(tempArray[0] + ".0");
                } else if (tempArray2.length - 1 == 1) {
                    cidrMerge.setIp(tempArray[0] + ".0.0");
                } else if (tempArray2.length - 1 == 0) {
                    cidrMerge.setIp(tempArray[0] + ".0.0.0");
                } else if (tempArray2.length - 1 == 3) {
                    cidrMerge.setIp(tempArray[0]);
                    cidrMerge.setBinaryIp(binaryString.toString());
                }
                cidrMerge.setLen(Integer.parseInt(tempArray[1]));

            } else {
                //省略长度型
                if (anIpPrefixArray.contains(".")) {
                    String[] tempArray=anIpPrefixArray.split("\\.");
                    if (tempArray.length - 1 == 2) {
                        cidrMerge.setIp(anIpPrefixArray + ".0");
                        cidrMerge.setLen(24);
                    } else if (tempArray.length - 1 == 1) {
                        cidrMerge.setIp(anIpPrefixArray + ".0.0");
                        cidrMerge.setLen(16);
                    } else if (tempArray.length - 1 == 0) {
                        cidrMerge.setLen(8);
                        cidrMerge.setBinaryIp(binaryString.toString());
                    } else if (tempArray.length - 1 == 3) {
                        cidrMerge.setIp(anIpPrefixArray);
                        cidrMerge.setLen(32);
                        cidrMerge.setBinaryIp(binaryString.toString());
                    }
                } else {
                    cidrMerge.setIp(anIpPrefixArray + ".0.0.0");
                    cidrMerge.setLen(8);
                }
            }
            String[] tt=cidrMerge.getIp().split("\\.");
            for (String aTt : tt) {
                String temp = String.format("%08d", Integer.valueOf(Integer.toBinaryString(Integer.parseInt(aTt))));
                binaryString.append(temp);
            }
            cidrMerge.setBinaryIp(binaryString.toString());
            cIDRMergeList.add(cidrMerge);
        }
        return cIDRMergeList;
    }
    /**
     * 判断ip前缀是否合法
     * @param binaryIp 二进制ip前缀
     * @return 是否合法
     */
    private static Boolean isLegal(String binaryIp,int len){
        if(len > 32){
            return false;
        }
        StringBuilder zeroString = new StringBuilder();
        for (int i=0; i < 32 - len; i++) {
            zeroString.append("0");
        }
        return binaryIp.substring(len, binaryIp.length()).equals(zeroString.toString());
    }

    /**
     * 根据ip地址为第一关键字 前缀长度为第二关键字进行前缀列表的排序
     * @param cIDRMergeList 前缀列表
     * @return 排序后的前缀列表
     */
    private static List<CIDRMerge> cIDRMergeListSort(List<CIDRMerge> cIDRMergeList){
        List<CIDRMerge> cIDRMergeListSortByIp = cIDRMergeList.stream().sorted(Comparator.comparing(CIDRMerge::getBinaryIp)).collect(Collectors.toList());
        for (int i=0; i < cIDRMergeListSortByIp.size()-1; i++) {
            if(cIDRMergeListSortByIp.get(i).getIp().equals(cIDRMergeListSortByIp.get(i+1).getIp()) && cIDRMergeListSortByIp.get(i).getLen() > cIDRMergeListSortByIp.get(i+1).getLen()){
                int  l = cIDRMergeListSortByIp.get(i).getLen();
                cIDRMergeListSortByIp.get(i).setLen(cIDRMergeListSortByIp.get(i+1).getLen());
                cIDRMergeListSortByIp.get(i+1).setLen(l);
            }
        }
        return cIDRMergeListSortByIp;
    }

    /**
     * 判断b的匹配集是否是a的匹配集的子集
     * @param a  ip前缀(列表)
     * @param b  ip前缀(列表)
     * @return 匹配集
     */
    private static Boolean isSubList(CIDRMerge a,CIDRMerge b){
        if(a.getIp().equals("0.0.0.0") && a.getLen()==0) {
            return true;
        }
        return b.len >= a.len && b.getBinaryIp().substring(0, a.len).equals(a.getBinaryIp().substring(0, a.len));
    }

    /**
     * 判断a和b的匹配集是否等于a1的匹配集
     * @param a
     * @param b
     * @return
     */
    private static Boolean isUnion(CIDRMerge a,CIDRMerge b){
        if(a.len == b.len){
            int a1 = a.len - 1;
            //判断a.ip+"/"+a1是否合法
            if (isLegal(a.getBinaryIp(),a1)) {
                //a1的匹配集范围
                return a.getBinaryIp().substring(0,a1).equals(b.getBinaryIp().substring(0,a1));
            }

        }
        return false;
    }

    /**
     * 从小到大合并前缀列表
     * @param cIDRMergeList 前缀列表
     * @return 合并后的前缀列表
     */
    private static void mergeCIDRMergeListFromMinToMax(List<CIDRMerge> cIDRMergeList){
        for (int i=0; i < cIDRMergeList.size()-1; i++) {
            for (int j=i+1;j < cIDRMergeList.size();j++){
                if(CIDRMerge.isSubList(cIDRMergeList.get(i),cIDRMergeList.get(j))){
                    cIDRMergeList.remove(cIDRMergeList.get(j));
                    --j;
                }
            }
        }
    }
    /**
     * 同级合并前缀列表
     * @param cIDRMergeList 前缀列表
     * @return 合并后的前缀列表
     */
    private static void mergeCIDRMergeListSameLevel(List<CIDRMerge> cIDRMergeList){
        for (int j=0; j < cIDRMergeList.size(); j++) {
            if(j+1 < cIDRMergeList.size() && CIDRMerge.isUnion(cIDRMergeList.get(j),cIDRMergeList.get(j+1))){
                cIDRMergeList.get(j).setLen(cIDRMergeList.get(j).getLen()-1);
                cIDRMergeList.remove(cIDRMergeList.get(j+1));
                if(j != 0){
                    j -= 2;
                }
            }
        }
    }
    public static void main (String[] args){
        List<CIDRMerge> cIDRMergeList;
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        scanner.nextLine();
        String[] ips = new String[n];
        for (int i=0; i < n; i++) {
            ips[i] = scanner.nextLine();
        }
        //处理读取的ip前缀数组,返回前缀列表
        cIDRMergeList = CIDRMerge.handleIncompleteIpPrefix(ips);
        //前缀列表排序
        List<CIDRMerge> cIDRMergeListSort = CIDRMerge.cIDRMergeListSort(cIDRMergeList);
        //从小到大合并前缀列表
        CIDRMerge.mergeCIDRMergeListFromMinToMax(cIDRMergeListSort);
        //同级合并
        CIDRMerge.mergeCIDRMergeListSameLevel(cIDRMergeListSort);
        if (cIDRMergeListSort != null && cIDRMergeListSort.size() > 0) {
            cIDRMergeListSort.forEach(cIDRMerge -> System.out.println(cIDRMerge.ip + "/" + cIDRMerge.len));
        }
    }
}

总结:运行超时导致只得80分,有时间优化一下,逻辑已经没有问题的,只是性能不满足。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值