当<对象按降序排序对象。比较器定义了吗?

时间:2013-05-14 18:24:59

标签: c++ sorting c++11 comparator

我有一个班级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函数,但我一直在寻找更短的东西。

5 个答案:

答案 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());

rbeginrend为您提供反向迭代器。

封装如果太混乱了:

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

实施例

取自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';
}

答案 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());