假设我有一个结构向量
struct foo {
int num;
char s;
};
vector<foo> vec;
s
可以是以下三个值之一:a
,b
或c
,而num
可以是任何正整数或负整数。
我想要的是
首先,根据num
对向量进行排序,然后对于num
的每组重复值,根据s
对它们进行排序,其中(a
我了解第一步很容易,并且可以通过谓词功能实现
bool compare (foo &a, foo &b) {
if(a.num < b.num) return true;
else return false;
}
和std::sort(vec.begin(), vec.end(), compare)
我坚持的是第二部分。根据{{1}}对向量中的重复值进行排序。我尝试在此谓词中添加另一个条件,并为另一个排序步骤创建一个单独的谓词,但是我似乎缺少了一些东西。
非常感谢您的帮助。谢谢!
答案 0 :(得分:3)
您可以将排序功能修改为:
bool compare (foo &a, foo &b) {
if(a.num < b.num) return true;
else if(a.num == b.num) return a.s < b.s;
return false;
}
答案 1 :(得分:2)
如果要基于num
进行排序,并且如果谓词中两个num
的值都相等,则可以按s
进行排序,这可以通过使用{{3} }
#include <tuple>
bool compare (foo &a, foo &b)
{
return std::tie(a.num, a.s) < std::tie(b.num, b.s);
}
如果您使用的是C ++ 98标准编译器而不是C ++ 11,则可以使用make_pair
#include <utility>
bool compare (foo &a, foo &b)
{
return std::make_pair(a.num, a.s) < std::make_pair(b.num, b.s);
}
与使用std::tie
相比,我的偏好是std::make_pair
。原因是,如果您在struct
中添加了第三个成员,并且想在num
和s
相等的情况下对该新成员进行排序,则使用{{1} }更易于更新,因为std::tie
仅适用于两个值:
make_pair
答案 2 :(得分:1)
我不推荐这种方法,但是您可以可以使用两次sort调用:对内部元素进行一次排序,然后对外部元素进行稳定的排序(尽管这样会更慢):
std::sort(vec.begin(), vec.end(),
[](foo const& f0, foo const& f1){ return f0.s < f1.s; });
std::stable_sort(vec.begin(), vec.end(),
[](foo const& f0, foo const& f1){ return f0.num < f1.num; });
另一种方法是首先根据外部条件对元素进行排序,然后根据内部条件对相等范围(即,根据外部条件相等)进行排序:
auto outer_cond = [](foo const& f0, foo const& f1) {
return f0.num < f1.num;
};
// sort elements according to the outer condition
std::sort(vec.begin(), vec.end(), outer_cond);
for (auto first = vec.begin(); first != vec.end();) {
// find equal range
first = std::adjacent_find(first, vec.end(),
[](foo const& f0, foo const& f1) { return f0.num == f1.num; });
auto last = first;
std::tie(first, last) = std::equal_range(first, vec.end(), *first, outer_cond);
// sort equal range according to the inner condition
std::sort(first, last,
[](foo const& f0, foo const& f1) { return f0.s < f1.s; });
first = last;
}
但是,使用合适的谓词对整个范围进行排序可能是最有效的。