如何在c++中有效地对四重结构体进行排序
How do I sort efficiently a quadruple structs in C++?
我有一个包含成员x,y,z和w的结构体。我如何有效地排序首先是x,然后是y, z,最后是c++中的w ?
如果您想实现字典排序,那么最简单的方法是使用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::tie
从boost实现这一点。元组库。
您可以使用std::tie
将结构体转换为std::tuple
,并使用字典比较std::tuple::operator<
。下面是对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
)自动选择。
关于效率,来自在线参考:
所有比较操作符都是短路的;它们不访问元组元素超出了确定结果所必需的范围比较。
如果您有c++ 11环境,请选择std::tie
而不是这里给出的手写解决方案。它们更容易出错,可读性更差。
此解决方案每个元素最多有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;
});
如果您滚动自己的比较操作符,那么您可以自由地将对象扔到std::map
s或调用std::sort
。此实现设计得很简单,因此您可以在需要时轻松验证和修改它。通过只使用operator<
来比较x, y, z和w,如果这些变量不具有可比性(例如,如果它们是你自己的结构体而不是int, double, std::string等),它可以最大限度地减少你可能需要实现的操作符的数量。
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;
}
- 根据用户回答声明"Players"。用户选择玩家数量。播放器是结构体
- 结构体 S { int align; } 之间的区别;(struct 关键字后的名称)和 struct { int al
- C++ - 如何在结构向量中找到结构体一个成员的最大值?
- 包含 std::list 的结构体的 C++ 初始化
- 结构体和类的不同大小(),彼此具有相同的字段类型
- 如何使用结构体的向量数组?
- 如何使用结构体在C++中更改这些代码?
- 无法在 Mosquitto MQTT Broker 插件上访问结构体 mosquitto 的元素
- 我应该如何在C++中使用结构体解决输入失败的问题?
- Qsort() 比较结构体整数的总和
- 如何使用迭代器指向结构体c++的向量
- 在C++中使用链表的堆栈实现中,访问结构体headNode成员count和top会导致运行时错误
- 如何获取结构体成员的地址
- 创建结构体向量,表达式:向量下标超出范围
- boost::任何带有结构体和无符号整数
- 如何在构造函数中初始化结构体的动态数组?
- 只写结构体的某些字段
- 如何在c++中有效地对四重结构体进行排序
- c++编译器抱怨重定义结构体
- 如何在c++中重置结构体中的所有变量