我有一个班级A
和一个<
比较器。如何使用它们以降序顺序对A
数组进行排序?
class A {
...
};
class LessA {
bool operator()(const A& a1, const A& a2) const {
...
}
}
vector<A> v;
sort(v.begin(), v.end(), ???);
我想我应该用基于???
的内容替换LessA
,但我无法弄清楚应该在那里发生什么。我想过使用lambda函数,但我一直在寻找更短的东西。
答案 0 :(得分:7)
如果要根据LessA
比较器定义的关系进行排序,只需传递LessA
的实例作为第三个参数(并且,因为您使用的是C ++ 11,所以更喜欢全局std::begin()
和std::end()
函数):
std::sort(std::begin(a), std::end(a), LessA());
// ^^^^^^^
现在,如果您的LessA()
表达<
关系,并且您想根据相反的标准进行排序,则可以执行以下操作:
std::sort(std::begin(a), std::end(a),
[] (A const& a1, A const& a2))
{
return LessA()(a2, a1);
}
你可以做的另一件事是让你的自定义比较器接受一个决定它应该如何执行比较的参数:
class CompA {
bool lessThan;
public:
CompA(bool lessThan) : _lessThan(lessThan) { }
bool operator()(const A& a1, const A& a2) const {
if (_lessThan)
{
// return true iff a1 < a2;
}
else
{
// return true iff a1 > a2;
}
}
};
然后你可以用这种方式按升序排序:
std::sort(std::begin(a), std::end(a), CompA(true));
这种方式按降序排序:
std::sort(std::begin(a), std::end(a), CompA(false));
给定原始LessA
比较器的另一种可能性是使用std::bind
将参数的顺序交换到自定义比较器:
LessA comp;
using namespace std::placeholders;
std::sort(std::begin(v), std::end(v),
std::bind(&LessA::operator(), comp, _2, _1));
答案 1 :(得分:6)
向后排序范围:
vector<A> v;
sort(v.rbegin(), v.rend(), LessA());
封装如果太混乱了:
void reverse_sort(vector<A>& v) {
sort(v.rbegin(), v.rend(), LessA());
}
用法:
vector<A> v;
reverse_sort(v);
答案 2 :(得分:2)
使用std::greater
作为比较仿函数。默认(std::less
)将为您提供升序;这会给你一个降序。 (您需要添加using namespace std::rel_ops;
(link)语句或明确定义operator>
。)
#include <algorithm>
#include <functional>
#include <array>
#include <iostream>
int main()
{
std::array<int, 10> s = {5, 7, 4, 2, 8, 6, 1, 9, 0, 3};
// sort using the default operator<
std::sort(s.begin(), s.end());
for (int a : s) {
std::cout << a << " ";
}
std::cout << '\n';
// sort using a standard library compare function
std::sort(s.begin(), s.end(), std::greater<int>());
for (int a : s) {
std::cout << a << " ";
}
std::cout << '\n';
// sort using a custom functor
struct {
bool operator()(int a, int b)
{
return a < b;
}
} customLess;
std::sort(s.begin(), s.end(), customLess);
for (int a : s) {
std::cout << a << " ";
}
std::cout << '\n';
// sort using a lambda
std::sort(s.begin(), s.end(), [](int a, int b) {
return b < a;
});
for (int a : s) {
std::cout << a << " ";
}
std::cout << '\n';
}
答案 3 :(得分:0)
给定实现lt(a, b)
的函数a<b
,您可以通过返回a>=b
来创建实现!lt(a, b)
的函数。要实施>
,您需要返回!lt(b, a) && !(lt(a,b) || lt(b,a))
。
lt(a, b) || lt(b, a)
相当于a!=b
,因此上述内容相当于a>=b && a!=b
,后者缩减为a>b
。
然而,你可能只能std::not2(LessA())
逃脱。这将与>=
排序,它将按降序排序。
答案 4 :(得分:-1)
让()
类的LessA
运算符返回!(a1 < a2)
并将其传递给:
std::sort(v.begin(), v.end(), LessA());