7

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

4

5 回答 5

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));
于 2013-05-14T18:26:42.313 回答
6

向后排序范围:

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);
于 2013-05-14T18:57:47.510 回答
2

用于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';
}
于 2013-05-14T19:01:50.820 回答
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!=bwhich 归约为a>b

但是,您可能只需std::not2(LessA()). That will sort with >=which 将按降序排序。

于 2013-05-15T20:57:39.263 回答
-1

使类的()运算符LessA返回!(a1 < a2)并像这样传递它:

std::sort(v.begin(), v.end(), LessA());
于 2013-05-14T18:27:03.813 回答