简体   繁体   English

定义<比较器时,按降序对对象排序?

[英]Sort objects in descending order when the < comparator is defined?

I have a class A and a < comparator. 我有一个A类和一个<比较器。 How can I use them to sort an array of A in descending order? 如何使用它们按降序A数组进行排序?

class A {
...
};

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

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

I suppose I should replace the ??? 我想我应该更换??? with something based on LessA , but I can't figure out what should go in there. 基于LessA东西,但我无法弄清楚那里应该有什么。 I thought of using a lambda function, but I was looking for something shorter. 我想过使用lambda函数,但我一直在寻找更短的东西。

If you want to sort according to the relation defined by your LessA comparator, just pass an instance of LessA as the third argument (and, since you are using C++11, prefer the global std::begin() and std::end() functions): 如果你想根据LessA比较器定义的关系进行排序,只需传递一个LessA实例作为第三个参数(并且,因为你使用的是C ++ 11,所以更喜欢全局std::begin()std::end()函数):

std::sort(std::begin(a), std::end(a), LessA());
//                                    ^^^^^^^

Now if your LessA() expresses the < relation and you want to sort according to the opposite criterion, you could do: 现在,如果你的LessA()表达< relation并且你想根据相反的标准排序,你可以这样做:

std::sort(std::begin(a), std::end(a), 
    [] (A const& a1, A const& a2))
{
    return LessA()(a2, a1);
}

Another thing you could do is to let your custom comparator accept an argument that determines how it should perform the comparison: 您可以做的另一件事是让您的自定义比较器接受一个参数来确定它应该如何执行比较:

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

You could then use it this way to sort in ascending order: 然后,您可以使用这种方式按升序排序:

std::sort(std::begin(a), std::end(a), CompA(true));

And this way to sort in descending order: 这种方式按降序排序:

std::sort(std::begin(a), std::end(a), CompA(false));

Another possibility, given your original LessA comparator, is to use std::bind to swap the order of the arguments to your custom comparator: 给定原始LessA比较器的另一种可能性是使用std::bind将参数的顺序交换到自定义比较器:

LessA comp;
using namespace std::placeholders;
std::sort(std::begin(v), std::end(v), 
    std::bind(&LessA::operator(), comp, _2, _1));

Sort the range backwards: 向后排序范围:

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

rbegin , and rend give you reverse iterators. rbeginrend给你反向迭代器。

Encapsulate if it's too confusing: 封装,如果它太混乱:

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

Usage: 用法:

vector<A> v;
reverse_sort(v);

Use std::greater for the comparison functor. 使用std::greater作为比较仿函数。 The default ( std::less ) will give you an ascending order; 默认( std::less )将为您提供升序; this will give you a descending order. 这会给你一个降序。 (You'll need to add a using namespace std::rel_ops; ( link ) statement or explicitly define operator> as well.) (您还需要添加using namespace std::rel_ops;link )语句或显式定义operator> 。)

Example

Taken from cppreference.com 取自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';
}

Given a function lt(a, b) that implements a<b , you can create a function that implements a>=b by returning !lt(a, b) . 给定实现a<b的函数lt(a, b) ,您可以通过返回!lt(a, b)来创建实现a>=b的函数。 To implement > , you need to return !lt(b, a) && !(lt(a,b) || lt(b,a)) . 要实现> ,你需要返回!lt(b, a) && !(lt(a,b) || lt(b,a))

lt(a, b) || lt(b, a) lt(a, b) || lt(b, a) is equivalent to a!=b , so the above is equivalent to a>=b && a!=b which reduces to a>b . lt(a, b) || lt(b, a)相当于a!=b ,所以上面等于a>=b && a!=b ,它减少到a>b

However, you can probably get away with just std::not2(LessA()) . 但是,你可以使用std::not2(LessA()) That will sort with >= which will sort in descending order. 这将按>=排序,它将按降序排序。

LessA类的()运算符返回!(a1 < a2)并将其传递给:

std::sort(v.begin(), v.end(), LessA());

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM