Сортировать объекты в порядке убывания, когда & lt; компаратор определяется?

У меня есть класс A и < компаратор. Как я могу использовать их для сортировки массива A в нисходящий порядок?

class A {
...
};

class LessA {
bool operator()(const A& a1, const A& a2) const {
...
}
}

vector<A> v;
sort(v.begin(), v.end(), ???);

Я полагаю, я должен заменить ??? с чем-то основанным на LessA, но я не могу понять, что должно идти туда. Я думал об использовании лямбда-функции, но я искал что-то более короткое.

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));
7

Другие решения

Сортировка диапазона в обратном направлении:

vector<A> v;
sort(v.rbegin(), v.rend(), LessA());

rbegin, а также rend дать вам обратные итераторы.

Инкапсулируйте, если это слишком запутанно:

void reverse_sort(vector<A>& v) {
sort(v.rbegin(), v.rend(), LessA());
}

Использование:

vector<A> v;
reverse_sort(v);
6

использование std::greater для функтора сравнения. По умолчанию (std::less) даст вам восходящий порядок; это даст вам нисходящий порядок. (Вам нужно будет добавить using namespace std::rel_ops; (ссылка на сайт) заявление или явное определение operator> также.)

Взято из cppreference.com

#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';
}
2

Учитывая функцию 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()), Это будет сортировать с >= который будет сортировать в порядке убывания.

0

Сделать () оператор LessA возвращение класса !(a1 < a2) и передать это так:

std::sort(v.begin(), v.end(), LessA());
-1
По вопросам рекламы [email protected]