Title
Can correctly read n total of 3 types (standard type, omit suffix type, omit length type) ip address list. It is difficult
for you to simplify the
solution to the prefix list with the smallest number of equivalent IPs . Fortunately, it has been given, just follow Prompt 3 steps
Ideas
Use the following method to save the ip address table
- In the second step, the third step is to delete the intermediate entry, using list is convenient and efficient
- The pair defines <priority is frist, second we directly put ip in first length and second in second to meet the meaning of the question
- unsinged int occupies 32 bits, which is exactly the length of the ip address, and the extracted value depends on the shift operation
list<pair<unsigned int, unsigned int>>iplist;
Follow the prompts on the back
Code
#include <iostream>
#include <list>
#include <string>
#include <fstream>
#include <sstream>
#include <algorithm>
using namespace std;
list<pair<unsigned int, unsigned int>>iplist;
//#define DEBUG
void input() {
#ifdef DEBUG
fstream cin("input.txt");
#endif
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin >> n;
cin.get();
while (n--)
{
unsigned int ip = 0, pre;
string temp;
getline(cin, temp);
stringstream strs;
strs << temp;
int point = count(temp.begin(), temp.end(), '.');
for (int i = 0; i < point + 1; ++i) {
ip <<= 8;
int tip;
strs >> tip;
strs.get();
ip += tip;
}
for (int i = 0; i < 3 - point; i++)ip <<= 8;
if (temp.find('/') != string::npos) {//省略后缀和标准
strs >> pre;
}
else {//省略长度
pre = (point + 1) * 8;
}
iplist.push_back({ ip, pre });
}
iplist.sort();//pair中已经定义了<小于优先级为先比较first再比较second
//处理好3种输入和排序已经60分了
}
void fun() {
for (auto i = iplist.begin(), j = ++iplist.begin(); j != iplist.end(); ) {//从小到大合并 80分
if (i->second <= j->second &&
i->first >> (32 - i->second) == j->first >> (32 - i->second))
{
j = iplist.erase(j);
}
else {
++i; ++j;
}
}
for (auto i = iplist.begin(), j = ++iplist.begin(); j != iplist.end();) {//同级合并100分
if (i->second != 0 &&//a次合法长度必须大于0才能减,其实后面想也没必要长度为0早就被上面合并为一个了进不来这
i->second == j->second &&
((i->first >> (32 - i->second)) ^ (j->first >> (32 - i->second))) == 1)//只有最后一位不同
{
--(i->second);
j = iplist.erase(j);
if (i != iplist.begin()) {//提示中要求往前跳
--i; --j;
}
}
else {
++i; ++j;
}
}
}
int main()
{
input();
fun();
for (auto x : iplist) {
for (int i = 0; i < 4; ++i, x.first <<= 8) {
cout << (x.first >> 24);
if (i != 3)cout << '.';
}
cout << '/' << x.second << endl;
}
}
Homemade test data
4
6
7.0.0.0/8
4.0.0/8
4.0/7
能测试提示中的3个步骤
答案4.0.0.0/6