思路:
如题,用vector存储ip排序,之后再装入list链表中进行插入删除,可避免因大量插入删除而导致的运行超时。
易错点:
之前发布的文章有详细说明,还有一些自己编写的例子,有需要的可以查阅使用。
链接:
https://blog.csdn.net/qq_26873647/article/details/104188744.
关于stl标准模板库中的list容器具体函数功能和使用可以参考:
链接:
http://www.cplusplus.com/reference/.
#include<bits/stdc++.h>
using namespace std;
struct node{
int ip[4];
int len;
};
vector<node> vip;
list<node> lip;
//比较函数
bool cmp(node a,node b){
for(int i=0;i<4;i++){
if(a.ip[i]!=b.ip[i])return a.ip[i]<b.ip[i];
}
return a.len<b.len;
}
//从小到大合并
bool compare(node a,node b){
int piror=8-a.len%8;
int range=pow(2,piror)-1;
int t=a.len/8;
for(int i=0;i<t;i++){
if(a.ip[i]!=b.ip[i])return false;
}
if(b.ip[t]<=a.ip[t]+range){
return true;
}
return false;
}
//同级合并--已完善
bool combine(node a,node b,node &neo){ //合并函数
if(a.len!=b.len)return false;
neo.len=a.len-1;
for(int i=0;i<4;i++){
neo.ip[i]=a.ip[i];
}
if(compare(neo,a)&&compare(neo,b)){ //即将要合并的ip是否是合成ip的子集
int piror=8-neo.len%8;
int range=pow(2,piror)/2;
int t=neo.len/8;
int m=pow(2,piror);
if(neo.ip[t]%m!=0)return false ;//判断neo是否合法
for(int i=0;i<t;i++){
if(a.ip[i]!=b.ip[i])return false;
}
if(b.ip[t]==a.ip[t]+range){
return true;
}
return false;
}
}
void table(string str){ //制表
node temp;
int p=str.find('/'),i=0;
temp.len=stoi(str.substr(p+1));
str=str.substr(0,p);
while((p=str.find('.'))!=-1){
str[p]=' ';
}
stringstream ss;
string s;
ss<<str;
while(ss>>s){
temp.ip[i++]=stoi(s);
}
vip.push_back(temp);
}
void standard(string &str){ //IP标准化
int t=3,flag=1,p;
for(int i=0;i<str.size();i++){
if(str[i]=='.')t--;
if(str[i]=='/')flag=0;
}
if(flag){
int len=(4-t)*8;
str=str+"/"+to_string(len);
}
p=str.find('/');
while(t--){
str.insert(p,".0");
}
}
int main(){
ios::sync_with_stdio(false);
//输入
int n;
cin>>n;
for(int i=0;i<n;i++){
string str;
cin>>str;
//标准化
standard(str);
//制表
table(str);
}
//排序
sort(vip.begin(),vip.end(),cmp);
for(auto it:vip){
lip.push_back(it);
}
//从小到大合并
list<node>::iterator cur,next;
for(cur=lip.begin();cur!=lip.end();){
if(++cur==lip.end())break;
next=cur--;
if(compare(*cur,*next)){
lip.erase(next);
}
else cur++;
}
//同级合并--已完善
for(cur=lip.begin();cur!=lip.end();){
next=cur;
next++;
if(next==lip.end())break;
node neo;
if(combine(*cur,*next,neo)){
next++;
cur=lip.erase(cur,next);
lip.insert(cur,neo);
cur--;
if(cur!=lip.begin())cur--;
}
else cur++;
}
//输出
for(auto it:lip){
for(int i=0;i<4;i++){
cout<<it.ip[i];
if(i<3)cout<<'.';
}
cout<<'/'<<it.len<<endl;
}
return 0;
}