我有一个包含成员x,y,z和w的结构。我如何有效排序 先用x,然后是y,用z,最后是用C ++中的w?
答案 0 :(得分:9)
如果要实现字典排序,那么最简单的方法是使用std::tie
来实现小于或大于比较的运算符或仿函数,然后在集合上使用std::sort
你的结构。
struct Foo
{
T x, y, z, w;
};
....
#include <tuple> // for std::tie
bool operator<(const Foo& lhs, const Foo& rhs)
{
// assumes there is a bool operator< for T
return std::tie(lhs.x, lhs.y, lhs.z, lhs.w) < std::tie(rhs.x, rhs.y, rhs.z, rhs.w);
}
....
#include <algorithm> // for std::sort
std::vector<Foo> v = ....;
std::sort(v.begin(), v.end());
如果Foo
没有自然排序,最好定义比较仿函数而不是实现比较运算符。然后,您可以将这些传递给sort:
bool cmp_1(const Foo& lhs, const Foo& rhs)
{
return std::tie(lhs.x, lhs.y, lhs.z, lhs.w) < std::tie(rhs.x, rhs.y, rhs.z, rhs.w);
}
std::sort(v.begin(), v.end(), cmp_1);
如果您没有C ++ 11 tuple
支持,则可以使用std::tr1::tie
(使用标头<tr1/tuple>
)或使用boost.tuple library来实现此功能}}
答案 1 :(得分:6)
您可以使用std::tuple
将结构转换为std::tie
,并使用字典比较std::tuple::operator<
。这是使用lambda到std::sort
#include <algorithm>
#include <tuple>
#include <vector>
struct S
{
// x, y, z, w can be 4 different types!
int x, y, z, w;
};
std::vector<S> v;
std::sort(std::begin(v), std::end(v), [](S const& L, S const& R) {
return std::tie(L.x, L.y, L.z, L.w) < std::tie(R.x, R.y, R.z, R.w);
});
此示例为std:sort
提供了一个即时比较运算符。如果您总是希望使用字典比较,则可以编写由bool operator<(S const&, S const&)
或std::sort
和std::set
等有序关联容器自动选择的非成员std::map
关于效率,来自online reference:
所有比较运算符都是短路的;他们不访问元组 超出确定结果所必需的元素 比较。
如果您有C ++ 11环境,请选择此处给出的手写解决方案std::tie
。它们更容易出错且可读性更低。
答案 2 :(得分:2)
如果您推送自己的比较运算符,则可以自由地将对象放入std::map
或调用std::sort
。此实现设计简单,因此您可以根据需要轻松验证和修改它。通过仅使用operator<
来比较x,y,z和w,如果这些变量不是已经可比较的话,它可以最小化您可能需要实现的运算符的数量(例如,如果它们是您自己的结构而不是整数,则加倍,std :: strings等。)。
bool operator<(const Q& lhs, const Q& rhs)
{
if (lhs.x < rhs.x) return true;
if (rhs.x < lhs.x) return false;
if (lhs.y < rhs.y) return true;
if (rhs.y < lhs.y) return false;
if (lhs.z < rhs.z) return true;
if (rhs.z < lhs.z) return false;
if (lhs.w < rhs.w) return true;
return false;
}
有时,类型将定义一个返回-1,0或1的比较函数,以指示小于,等于或大于两者,作为支持<
,<=
的实现的方式,==
,!=
,>=
和>
,还因为有时会<
,!=
或>
会重复很多工作(考虑比较只有最后一个字符不同的长文本字符串)。如果x,y,z和w恰好属于这种类型且具有更高性能的比较功能,则可以通过以下方式提高整体性能:
bool operator<(const Q& lhs, const Q& rhs)
{
int c;
return (c = lhs.x.compare(rhs.x) ? c :
(c = lhs.y.compare(rhs.y) ? c :
(c = lhs.z.compare(rhs.z) ? c :
lhs.w < rhs.w;
}
答案 3 :(得分:2)
此解决方案每个元素最多进行4次比较 - 比较并且不需要构建其他对象:
// using function as comp
std::sort (quadrupleVec.begin(), quadrupleVec.end(), [](const Quadruple& a, const Quadruple& b)
{
if (a.x != b.x)
return a.x < b.x;
if (a.y != b.y)
return a.y < b.y;
if (a.z != b.z)
return a.z < b.z;
return a.w < b.w;
});