我需要比较 IP 地址列表并按逆字典顺序对它们进行排序。
字典排序的示例(按第一个字节,然后按第二个字节,依此类推):
- 1.1.1.1
- 1.2.1.1
- 1.10.1.1
相应地,反过来:
- 1.10.1.1
- 1.2.1.1
- 1.1.1.1
如何编写一个比较器来按此顺序比较地址,如果存储 IP 地址的数据结构是常规 int,即将八位字节打包成 int 并以整数的字节存储:
using ip = int;
using ip_pool = std::vector<ip>;
ip make_ip(const std::vector<std::string>& splitted)
{
validate_ip(splitted);
int _3 = std::stoi(splitted[0]);
int _2 = std::stoi(splitted[1]);
int _1 = std::stoi(splitted[2]);
int _0 = std::stoi(splitted[3]);
return _3 << 24 | _2 << 16 | _1 << 8 | _0;
}
我仍然有这个比较器,但由于某种原因,它对地址进行了错误的排序:整个地址池分为两部分,每部分都按相反的字典顺序排序,但不是连续的。这是为什么?怎样做才正确呢?
void sort_lexicographically(ip_pool& pool)
{
std::sort(pool.begin(), pool.end(), std::greater<int>());
/*std::sort(pool.begin(), pool.end(), [](const int& lhs, const int& rhs) {
return ((lhs >> 24 & 0xFF) > (rhs >> 24 & 0xFF) &&
(lhs >> 16 & 0xFF) > (rhs >> 16 & 0xFF) &&
(lhs >> 8 & 0xFF) > (rhs >> 8 & 0xFF) &&
(lhs & 0xFF) > (rhs & 0xFF));
});*/
}
地址沿着这条线划分
1.231.69.33
1.87.203.225
1.70.44.170
1.29.168.152
1.1.234.8
222.173.235.246
222.130.177.64
222.82.198.61
222.42.146.225
220.189.194.162
参见https://gcc.godbolt.org/z/K5E9ff4Tf
如果您有相反顺序的八位字节,请添加相反的顺序,例如,像这样......