zoukankan      html  css  js  c++  java
  • ip覆盖算法

     

    注释清晰,思路引导版:

    import java.io.*;
    import java.util.*;
    public class Main{
        static class Addr{
            String addrStr;
            int mask;
            int addr;
            public Addr(String addrStr, int mask, int addr){this.addrStr = addrStr; this.mask = mask; this.addr = addr;}
        }
        public static void main(String[] args) throws IOException{
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            int n = Integer.parseInt(br.readLine());
            LinkedList<Addr> list = new LinkedList<>();
            while(n-->0){
                String addrStr = br.readLine();//192.168.0.0/16
                String[] strs = addrStr.split("/");//[192.168.0.0,16]
                int mask = Integer.parseInt(strs[1]);//16
                strs = strs[0].split("\.");//[192,168,0,0]
                //下面一句话含义就是将各个位置【最后一位二进制8位不懂,倒数第二位应该在倒数八位后所以向左移动8位,一次类推构建成ip,然后使用|合并(因为不同ip位数对应位置都是0,因此使用|来连接)】
                int addr = (Integer.parseInt(strs[0])<<24) | (Integer.parseInt(strs[1])<<16) | (Integer.parseInt(strs[2])<<8) | Integer.parseInt(strs[3]);
                boolean flag = true;
                //遍历列表,如果发现有我已经可以覆盖某个,那么移除它,如果发现我已经被覆盖了,那么直接退出就好了
                for(Iterator<Addr> it = list.iterator(); it.hasNext(); ){
                    Addr tmp = it.next();
                    //如果我覆盖的更广,并且【异或,相同为0,不同为1】找出不同的,向右移动我可以32-mask位,【如mask为1的时候,我只需要考虑第一位进制就好,后面31位都不需要考虑】
                    //我覆盖的更广,并且和我前几位是相同的
                    if(mask < tmp.mask && ( (addr ^ tmp.addr) >>> (32-mask) == 0) ) it.remove();
                    //覆盖是相同的,但是我覆盖的面比当前列表中有的小,那么不需要将我加进去了
                    //这里判断如果我本身覆盖面小(也就是mask大) 并且列表中的这个可以满足覆盖我(注意是列表中的,这里32减去的是item.mask)
                    if(mask >= tmp.mask && ( (addr ^ tmp.addr) >>> (32-tmp.mask) == 0) ){flag = false; break;}
                }
                if(flag) list.add(new Addr(addrStr,mask,addr));
            }
            System.out.println(list.size());
            for(Iterator<Addr> it = list.iterator(); it.hasNext(); ){
                Addr tmp = it.next();
                System.out.println(tmp.addrStr);
            }
        }
    }

    无注释,个人精简版:

    import java.util.LinkedList;
    import java.util.Scanner;
    
    public class Main03 {
        static class Addr{
            String ipStr;
            int mask;
            int addr;
    
            public Addr(String ipStr, int mask, int addr) {
                this.ipStr = ipStr;
                this.mask = mask;
                this.addr = addr;
            }
        }
        public static void main(String[] args) {
            Scanner s=new Scanner(System.in);
            while (s.hasNext()){
                int k=s.nextInt();
                LinkedList<Addr> resList=new LinkedList<>();
                while (k-->0){
                    String ipStr=s.next();
                    String[] strs=ipStr.split("/");
                    int mask=Integer.parseInt(strs[1]);//可以覆盖的数量
                    strs=strs[0].split("\.");//每一项就是一块ip地址
                    int addr=(Integer.parseInt(strs[0])<<24)|(Integer.parseInt(strs[1])<<16)|(Integer.parseInt(strs[2])<<8)|(Integer.parseInt(strs[3]));
                    boolean isNeedAdd=true;//是否需要将这个加进去
                    LinkedList<Addr> removeList=new LinkedList<>();
                    for (Addr item : resList) {
                        if(mask<item.mask&&((addr^item.addr)>>(32-mask)==0))removeList.add(item);//使用for( : )不能直接移除,否则会报异常,但是使用iterator可以哦
                        //这里判断如果我本身覆盖面小(也就是mask大) 并且列表中的这个可以满足覆盖我(注意是列表中的,这里32减去的是item.mask)
                        if(mask>=item.mask&&((addr^item.addr)>>(32-item.mask)==0)){
                            isNeedAdd=false;
                            break;
                        }
                    }
                    for (Addr addr1 : removeList) {
                        resList.remove(addr1);
                    }
                    if(isNeedAdd){
                        resList.add(new Addr(ipStr,mask,addr));
                    }
                }
                System.out.println(resList.size());
                for (Addr item : resList) {
                    System.out.println(item.ipStr);
                }
            }
        }
    }
  • 相关阅读:
    蜘蛛禁止访问文件
    基于PhalApi的Smarty拓展 (视图层的应用)
    MySQL数据库存表情
    查看PHP版本等相关信息
    读取数据库表信息
    nginx简介
    Redis发布订阅
    Redis持久化
    Redis主从复制
    Redis的Java客户端Jedis
  • 原文地址:https://www.cnblogs.com/ningxinjie/p/13538347.html
Copyright © 2011-2022 走看看