201812-3 CIDR合并(80)

#include<bits/stdc++.h>
#define _for(i,a,b) for(int i=a;i<b;i++)
using namespace std;

const string dic[4] = {"/8", "/16", "/24", "/32"};
struct IP{
    int a, b, c, d, base, delta;
    int suffix;
    IP(int a = 0, int b = 0, int c = 0, int d = 0, int suffix = 0):a(a), b(b), c(c), d(d), suffix(suffix){
        base = a*256*256*256 + b*256*256 + c*256 + d;
        delta = 1<<(32 - suffix);
    }
    bool operator<(const IP& ip)const{
        return a != ip.a ? a < ip.a : (b != ip.b ? b < ip.b : (c != ip.c ? c < ip.c : d < ip.d));
    }
    bool operator==(const IP& ip)const{
        return a == ip.a && b == ip.b && c == ip.c && d == ip.d;
    }
};

vector<IP>ips;

IP getIP(string& ip)
{
    for(int i = 0; i < ip.size(); i++)
        if(ip[i] == '.' || ip[i] == '/') ip[i] = ' ';
    stringstream ss(ip);
    int a, b, c, d, n;
    ss >> a >> b >> c >> d >> n;
    return IP(a, b, c, d, n);
}
void insertToIPList(string& s)
{
    string ss = s.substr(0, s.find('/') == -1 ? s.size() : s.find('/'));

    //1.获取前面的点分十进制部分
    int cnt = 0, pos = -1;
    for(int i = 0; i < s.size(); i++){
        if(s[i] == '.'){
            cnt++;
            pos = i;
        }
    }
    for(int i = 0; i < 3 - cnt; i++){
        ss += ".0";
    }

    //2.获取掩码位数
    if(s.find('/') != -1){
        ss += s.substr(s.find('/'), s.size() - s.find('/'));
    }else{
        ss += dic[cnt];
    }
    //cout << ss << endl;
    ips.push_back(getIP(ss));
}

bool ip1_Include_ip2(IP& ip1, IP& ip2)
{
    int l1 = ip1.base, r1 = l1 + ip1.delta;
    int l2 = ip2.base, r2 = l2 + ip2.delta;
    return l1 <= l2 && r1 >= r2;
}

void union1()
{
    int n = ips.size();
    for(int i = 0; i < n - 1; i++){ if(ips[i].base != -1)
        for(int j = i + 1; j < n; j++){ if(ips[j].base != -1)
            if(ip1_Include_ip2(ips[i], ips[j])){
                ips[j].base = -1;
            }
        }
    }
    vector<IP>ipss;
    for(int i = 0; i < n; i++){
        if(ips[i].base != -1){
            ipss.push_back(ips[i]);
        }
    }
    ips.clear();
    ips = ipss;
}

void union2()
{
    int n = ips.size();
    for(int i = 0; i < n - 1;){
        int j = i + 1;
        while(j < n && ips[j].base == -1) j++;
        if(j == n){
            i++;
            continue;
        }
        IP& a = ips[i];
        IP& b = ips[j];
        if(a.suffix == b.suffix && a.base + a.delta == b.base){
            IP c(a.a, a.b, a.c, a.d, a.suffix - 1);
            ips[i] = c;
            b.base = -1;
            for(int j = i - 1; j >= 0; j--){
                if(ips[j].base != -1){
                    i = j;
                    break;
                }
            }
        }else{
            i++;
        }
    }
    vector<IP>ipss;
    for(int i = 0; i < n; i++){
        if(ips[i].base != -1){
            ipss.push_back(ips[i]);
        }
    }
    ips.clear();
    ips = ipss;
}





int main()
{
    int n; cin >> n;
    while(n--){
        string s;
        cin >> s;
        insertToIPList(s);
    }
    sort(ips.begin(), ips.end());
    union1();
    union2();
    for(IP &ip : ips)
            cout << ip.a << '.' << ip.b << '.' << ip.c << '.' << ip.d << '/' << ip.suffix <<endl;
    return 0;
}





/*
101.6.6.0/24
101.6.6.128/25

101.6.6.0/24
101.6.7.0/24

*/

 

posted on 2019-03-12 11:16  nbsanshi  阅读(193)  评论(0编辑  收藏  举报

导航