CIDR合并:
按照题目中所给的方法进行模拟即可:
第一次用vector数据结构来进行处理:
#include<iostream>
#include<string>
#include<stdlib.h>
#include<vector>
#include<algorithm>
using namespace std;
string int2bin1(long long num)
{
string s="";
int i;
for(i = 1; i < 33; i++)
{
if((unsigned int)(num & 0x80000000) == (unsigned int)(0x80000000))
{
s=s+"1";
}
else
{
s=s+"0";
}
num = num << 1;
}
return s;
}
struct node
{
int t[4];
int k;
unsigned int value;
string str;
node(int q[4],int p)
{
for(int i=0;i<4;i++)
t[i]=q[i];
k=p;
value=t[3]+t[2]*256+t[1]*256*256+t[0]*256*256*256;
str=int2bin1(value);
}
};
vector<node> vec;
int chnum(string str)
{
int num=0;
for(int i=0;i<str.size();i++)
{
if(str[i]>='0'&&str[i]<='9')
num=num*10+str[i]-'0';
}
return num;
}
bool cmp(node a,node b)
{
if(a.value <b.value )
return true;
else if(a.value ==b.value &&a.k<b.k)
return true;
else
return false;
}
bool flag(node a,node b)//判断b的匹配集是否是a的匹配集的子集
{
if(a.k>b.k)
return false;
for(long long i=0;i<a.k;i++)
{
if(a.str[i]!=b.str[i])
return false;
}
return true;
}
void merge1()
{
vector<node>::iterator i=vec.begin();
vector<node>::iterator j=vec.begin();
for(++j;j!=vec.end();)
{
if(flag(*i,*j))
{
j=vec.erase(j);
}
else
{
++i;
++j;
}
}
}
bool flaged(node a,node b)
{
if(a.k!=b.k)
return false;
for(int i=0;i<a.k-1;++i)
{
if(a.str[i]!=b.str[i])
return false;
}
return a.str[a.k-1]!=b.str[a.k-1];
}
void merge2()
{
vector<node>::iterator i=vec.begin();
vector<node>::iterator j=vec.begin();
++j;
for(;j!=vec.end();)
{
if(flaged(*i,*j))
{
j=vec.erase(j);
--(*i).k;
//cout<<(*i).str<<endl;
//cout<<(*i).k<<endl;
if(i!=vec.begin())
{
--i;
--j;
}
}
else
{
++i;
++j;
}
}
}
int main()
{
int n;
scanf("%d",&n);
string s;
for(int i=0;i<n;i++)
{
//scanf("%s",s);
cin>>s;
//getline(cin,s);
int t1=s.find(".");
int t2=0;
int temp[4];
for(int i=0;i<4;i++)
temp[i]=0;
int temped=0;
int count=0;
while(t1!=s.npos)
{
temp[count++]=chnum(s.substr(t2,t1-t2));
s[t1]='|';
t2=t1+1;
t1=s.find(".");
}
if(count==0)//证明是2/3或者2这种类型
{
int t3=s.find("/");
if(t3==s.npos)
{
temp[0]=chnum(s);
count++;
temped=8;
}
else
{
temp[0]=chnum(s.substr(0,t3));
temped=chnum(s.substr(t3+1,s.length()-t3-1));
count++;
}
// temped=count*8;
}
else
{
int t3=s.find("/");
if(t3!=s.npos)
{
temp[count++]=chnum(s.substr(t2,t3-t2));
temped=chnum(s.substr(t3+1,s.length()-t3-1));
}
else
{
temp[count++]=chnum(s.substr(t2,s.length()-t2));
temped=count*8;
}
}
// for(int i=0;i<4;i++)
//cout<<temp[i]<<" ";
// cout<<endl;
// cout<<temped<<endl;
vec.push_back(node(temp,temped));
}
sort(vec.begin(),vec.end(),cmp);
// for(int i=0;i<vec.size();i++)
// cout<<vec[i].str<<" ";
merge1();
merge2();
for(int i=0;i<vec.size();i++)
{
for(int j=0;j<3;j++)
{
printf("%d.",vec[i].t[j]);
}
printf("%d/%d\n",vec[i].t[3],vec[i].k);
}
return 0;
}
第二次把vector改成list,由于list是双向链表,可以高效进行删除插入和排序操作,过了。
#include<iostream>
#include<string>
#include<stdlib.h>
#include<vector>
#include<algorithm>
#include<list>
using namespace std;
string int2bin1(long long num)//将10进制数转化为32位二进制数
{
string s="";//用来存储32位二进制数
int i;
for(i = 1; i < 33; i++)
{
if((unsigned int)(num & 0x80000000) == (unsigned int)(0x80000000))//是在把十六进制表示的0x80000000和传递过来的num 的值进行位运算 &
{
s=s+"1";
}
else
{
s=s+"0";
}
num = num << 1;
}
return s;
}
struct node
{
int t[4];//0~3分别存储从高位到低位的数值,两者之间用.来进行分割
int k;//表示len
unsigned int value;//根据a3,a2,a1,a0转化为10进制数
string str;
node(int q[4],int p)
{
for(int i=0;i<4;i++)
t[i]=q[i];
k=p;
value=t[3]+t[2]*256+t[1]*256*256+t[0]*256*256*256;
str=int2bin1(value);
}
bool operator<(node b)
{
if(value <b.value )
return true;
else if(value ==b.value &&k<b.k)
return true;
else
return false;
}
};
list<node> vec;
void fun1(node &d){
cout << d.t[0]<< "." << d.t[1] << "."<<d.t[2]<<"."<<d.t[3]<<"/"<<d.k<<endl;//用于后边list类型的输出
}
int chnum(string str)
{
int num=0;
for(int i=0;i<str.size();i++)
{
if(str[i]>='0'&&str[i]<='9')//将一个数字字符串转化为整数
num=num*10+str[i]-'0';
}
return num;
}
bool flag(node a,node b)//判断b的匹配集是否是a的匹配集的子集
{
if(a.k>b.k)//作为父集,k一定要小于等于
return false;
for(long long i=0;i<a.k;i++)
{
if(a.str[i]!=b.str[i])
return false;
}
return true;
}
void merge1()//进行第一步的合并
{
list<node>::iterator i=vec.begin();
list<node>::iterator j=vec.begin();
for(++j;j!=vec.end();)
{
if(flag(*i,*j))//如果j是i的子集,则删除j这个节点
{
j=vec.erase(j); //list的erase函数返回的是删除之后的下一个元素的位置
}
else
{
++i;
++j;
}
}
}
bool flaged(node a,node b) //判断a和b的匹配集的并集是否等于a'的匹配集
{
if(a.k!=b.k)
return false;
for(int i=0;i<a.k-1;++i)
{
if(a.str[i]!=b.str[i])
return false;
}
return a.str[a.k-1]!=b.str[a.k-1];//对于len的最后一位不相同,前边相同的情况则一定是并集的匹配集等于a的前缀和加上a的len-1
}
void merge2()//第二部合并,同级合并
{
list<node>::iterator i=vec.begin();
list<node>::iterator j=vec.begin();//迭代器
++j;
for(;j!=vec.end();)
{
if(flaged(*i,*j))//如果可以合并,删除j,i的len-1
{
j=vec.erase(j);
--(*i).k;
//cout<<(*i).str<<endl;
//cout<<(*i).k<<endl;
if(i!=vec.begin())//如果不是头节点,则一直返回到头节点进行比较
{
--i;
--j;
}
}
else
{
++i;
++j;
}
}
}
int main()
{
int n;
cin>>n;
string s;
for(int i=0;i<n;i++)
{
cin>>s;
//getline(cin,s);
int t1=s.find(".");//查询是否有.
int t2=0;
int temp[4];
for(int i=0;i<4;i++)
temp[i]=0;//用来存储每个节点所对应的4个值
int temped=0;//用来存储每个节点的len
int count=0;
while(t1!=s.npos)
{
temp[count++]=chnum(s.substr(t2,t1-t2));//将数字字符串转化为整数
s[t1]='|';//将所分析过的.掩盖
t2=t1+1;
t1=s.find(".");
}
if(count==0)//证明是2/3或者2这种类型
{
int t3=s.find("/");
if(t3==s.npos)//证明是2这种类型
{
temp[0]=chnum(s);
count++;
temped=8;
}
else
{
temp[0]=chnum(s.substr(0,t3));//证明是2/3这种类型
temped=chnum(s.substr(t3+1,s.length()-t3-1));
count++;
}
// temped=count*8;
}
else
{
int t3=s.find("/");//证明是2.3.4/3或者2.3.4这种类型
if(t3!=s.npos)
{
temp[count++]=chnum(s.substr(t2,t3-t2));//2.3.4/3这种类型
temped=chnum(s.substr(t3+1,s.length()-t3-1));
}
else
{
temp[count++]=chnum(s.substr(t2,s.length()-t2));//2.3.4这种类型
temped=count*8;
}
}
// for(int i=0;i<4;i++)
//cout<<temp[i]<<" ";
// cout<<endl;
// cout<<temped<<endl;
vec.push_back(node(temp,temped));//在list后边实现插入
}
vec.sort();//进行排序,在结构体中对<进行了重载
// sort(vec.begin(),vec.end(),cmp);
// for(int i=0;i<vec.size();i++)
// cout<<vec[i].str<<" ";
merge1();//第一次合并
merge2();//同级合并
//for(int i=0;i<vec.size();i++)
/*for(list<node>::iterator i=vec.begin();i!=vec.end();i++)
{
for(int j=0;j<3;j++)
{
cout<<(*i).t[j]<<".";
}
cout<<(*i).t[3]<<"/"<<(*i).k<<endl;
}*/
for_each(vec.begin(), vec.end(), fun1);//输出list中现有节点的相关信息
return 0;
}
说明:对于整数转化为32位二进制数是借鉴部分博客