CIDR合并

//读懂题意很重要..........

//substr(pos, n)//从某一位置开始截取长度为n的串.....

//++要想好怎么用   迭代器也要分配好....不然怎么都不出来结果...

/*
	思路:读入字符串,将字符串的/后的len,以及转化为标准形式的二进制串str 共同存在结构体里,
	按照先str,在len的形式从小到大排序;然后将其进行比较,即是否包含,不包含则进行合并,
	删除能合并的不能合并的则保留
	2
1.1.1.1/2
1.2.1.1/2
1.1.1.1/2


2
1.1.1.1/2
1.0
1.0.0.0/16
1.1.1.1/2
*/

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<list>
#include<algorithm>

using namespace std;

const int N = 1e5+5;

struct Node {
	int len;
	string str;
	bool operator <(const Node &a)const {
		return str==a.str?(len<a.len):(str<a.str);
	}
};

list<Node> S;

int ToInt(string s) {
	int t=0;

	for(int i=0; s[i]; i++) {
		t *= 10;
		t += (s[i]-'0');
	}
	return t;
}
void StringtoBit(string &s, int tmp) {
	int n=7;
	while(n>=0) {
		s[n--] = tmp%2+'0';
		tmp /= 2;
	}
}

int BittoString(string s) {
	int tmp = 0;
	for(int i=0; i<=7; i++) {
		tmp *= 2;
		tmp += (s[i]-'0');
	}
	return tmp;
}

void ToStandard(string s) {
	Node temp;
	string str(32, '0'), tmp;
	vector<string> v;
	string flag=".";
	int pre = 0, position=0, cnt = 0;
	while((position=s.find(flag,position))!=string::npos) {
		tmp = s.substr(pre, position-pre);
		v.push_back(tmp);

		position++;	
		pre = position;
	}

	if(s.find('/')!= string::npos) {
		position = s.find('/');
		tmp = s.substr(pre, position-pre);
		v.push_back(tmp);
		tmp = s.substr(position+1);

		temp.len = ToInt(tmp);
	} else if(v.size() == 0) {//没有. / 
		v.push_back(s);
		temp.len = 8;
	} else{
		tmp = s.substr(pre);
		v.push_back(tmp) ;
		temp.len = (v.size()*8);//没有/ 
	} 
	int pos=0;
	for(int i=0, j=0; i<v.size(); i++) {
		tmp = v[i];
		int tn = ToInt(tmp);
		int n=7;
		string newt = "";
		while(n>=0) {
			newt += tn%2+'0';
			tn /= 2;
			n--;
		}
		for(int k=7; k>=0; k--) {
			str[j++] = newt[k];
			if(tmp[k] !='0') pos = j;
		}
	}
	temp.str = str;
	S.push_back(temp);
}
int Subset(Node a, Node b) {
	string s1 = a.str, s2 = b.str;
	int len = a.len;

	for(int i=0; i<len; i++) {
		if(s1[i] != s2[i]) {
			return i;
		}
	}
	return len;
}
void print(string s,int len) {
	string s1=s.substr(0,8);
	string s2=s.substr(8,8);
	string s3=s.substr(16,8);
	string s4=s.substr(24,8);

	cout<<BittoString(s1)<<"."<<BittoString(s2)<<"."<<BittoString(s3)<<"."<<BittoString(s4)<<"/"<<len<<endl;

}

int main() {
	ios::sync_with_stdio(false);

	int T;

	cin >> T;
	string tmp;
	while(T--) {
		cin >> tmp;

		ToStandard(tmp);

	}
	S.sort();

	for(list<Node>::iterator it1=S.begin(); it1 != S.end(); ) {//迭代器可能有问题
		list<Node>::iterator it2=it1;
		it2++;
		if(it2 == S.end()) break;
		Node ttt = *it1, ttt2 = *it2;
		int tttt = Subset(ttt, ttt2);
		if(tttt == ttt.len) { //是子集
			it2 = S.erase(it2);
		} else if(tttt == ttt.len-1 && ttt.len == ttt2.len) { //同级合并
			S.erase(it2);
			ttt.len--;
			*it1 = ttt;

			if(it1 != S.begin()) {
				it1--;
			}

		} else {
			it1++;//向后继续判断
		}
	}
	for(list<Node>::iterator cur=S.begin(); cur!=S.end(); cur++)
		print((*cur).str, (*cur).len);
	return 0;
}

//调试版 

/*
	思路:读入字符串,将字符串的/后的len,以及转化为标准形式的二进制串str 共同存在结构体里,
	按照先str,在len的形式从小到大排序;然后将其进行比较,即是否包含,不包含则进行合并,
	删除能合并的不能合并的则保留
	2
1.1.1.1/2
1.2.1.1/2
1.1.1.1/2


2
1.1.1.1/2
1.0
1.0.0.0/16
1.1.1.1/2
*/

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<list>
#include<algorithm>

using namespace std;

const int N = 1e5+5;

struct Node {
	int len;
	string str;
	bool operator <(const Node &a)const {
		return str==a.str?(len<a.len):(str<a.str);
	}
};

list<Node> S;

int ToInt(string s) {
	int t=0;

	for(int i=0; s[i]; i++) {
		t *= 10;
		t += (s[i]-'0');
	}
//	sprintf(t, "%s", s);
	return t;
}
void StringtoBit(string &s, int tmp) {
	int n=7;
	while(n>=0) {
		s[n--] = tmp%2+'0';
		tmp /= 2;
	}
//	cout << s << endl;
}

int BittoString(string s) {
	int tmp = 0;
	for(int i=0; i<=7; i++) {
		tmp *= 2;
		tmp += (s[i]-'0');
	}
	return tmp;
}

void ToStandard(string s) {
	Node temp;
	string str(32, '0'), tmp;
//	cout << str << endl << s << endl;
	vector<string> v;
	//查找s 中flag 出现的所有位置。
	string flag=".";
	int pre = 0, position=0, cnt = 0;
	while((position=s.find(flag,position))!=string::npos) {
		//     cout<<"position : "<<position<<endl;
		tmp = s.substr(pre, position-pre);
		v.push_back(tmp);
	//	cout << pre << "-" << position << "=" << tmp << endl;

		position++;	
		pre = position;
	}

	if(s.find('/')!= string::npos) {
		position = s.find('/');
		tmp = s.substr(pre, position-pre);
	//	cout << pre << "-" << position << "=" << tmp << endl;
		v.push_back(tmp);
//	cout << tmp << ":" << ToInt(tmp) << endl;
		tmp = s.substr(position+1);

		temp.len = ToInt(tmp);
	} else if(v.size() == 0) {//没有. / 
//		cout << s << endl;
		v.push_back(s);
		temp.len = 8;
	} else{
		tmp = s.substr(pre);
		v.push_back(tmp) ;
		temp.len = (v.size()*8);//没有/ 
	} 
	int pos=0;
//	cout << v.size() << endl;
	for(int i=0, j=0; i<v.size(); i++) {
		tmp = v[i];
//		cout << tmp << endl;
		int tn = ToInt(tmp);
		int n=7;
	//	cout << tn << endl;
		string newt = "";
		while(n>=0) {
			newt += tn%2+'0';
			tn /= 2;
			n--;
		}
	//		cout << newt << endl;
		for(int k=7; k>=0; k--) {
			str[j++] = newt[k];
			//		cout << str << endl;
			if(tmp[k] !='0') pos = j;
		}
	}
	temp.str = str;
/*	if(position == string::npos) {
		temp.len = pos;
	}*/
	//cout << temp.str << "/" << temp.len << endl;
	S.push_back(temp);
}
int Subset(Node a, Node b) {
	string s1 = a.str, s2 = b.str;
	int len = a.len;

	for(int i=0; i<len; i++) {
		if(s1[i] != s2[i]) {
			//		cout << i << endl;
			return i;
		}
	}
//	cout << len << endl;
	return len;
}
void print(string s,int len) {
	string s1=s.substr(0,8);
	string s2=s.substr(8,8);
	string s3=s.substr(16,8);
	string s4=s.substr(24,8);
//	cout<<s1 <<"."<<s2<<"."<<s3<<"."<<s4<<"/"<<len<<endl;//标准形式 

	cout<<BittoString(s1)<<"."<<BittoString(s2)<<"."<<BittoString(s3)<<"."<<BittoString(s4)<<"/"<<len<<endl;

}

int main() {
	ios::sync_with_stdio(false);

	int T;

	cin >> T;
	string tmp;
	while(T--) {
		cin >> tmp;

		ToStandard(tmp);

	}
	S.sort();
//cout << S.size() << endl;


	for(list<Node>::iterator it1=S.begin(); it1 != S.end(); ) {//迭代器可能有问题
		list<Node>::iterator it2=it1;
		it2++;
		if(it2 == S.end()) break;
		Node ttt = *it1, ttt2 = *it2;
		int tttt = Subset(ttt, ttt2);
		//cout << tttt<<" " << ttt.len << "s" << ttt2.len << endl;
		if(tttt == ttt.len) { //是子集
			//	cout << "子集关系" << endl;
			it2 = S.erase(it2);
			//	it2 = it1++;
		} else if(tttt == ttt.len-1 && ttt.len == ttt2.len) { //同级合并
			//cout << "同级合并" << endl;
			S.erase(it2);
			//	it2 = it1++;
	//		cout << (*it1).str<< endl;
			ttt.len--;
			*it1 = ttt;

			//还需将其和前面进行比较看是否能同级合并
			if(it1 != S.begin()) {
				//		it2 = it1;
				it1--;
			}

		} else {
			//cout << "都不是" << endl;
			it1++;//向后继续判断
			//	it2++;
		}
	}
	for(list<Node>::iterator cur=S.begin(); cur!=S.end(); cur++)
		print((*cur).str, (*cur).len);
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值