2013-05-14 39 views
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函数,但我正在寻找更短的东西。

+0

http://www.cplusplus.com/reference/algorithm/sort/ – 2013-05-14 18:26:54

+0

拉姆达可能是您最好的选择。 – Joel 2013-05-14 18:36:04

回答

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

是的,但是会按升序排列'v'。我想要降序。 – 2013-05-14 18:28:49

+1

@PaulBaltescu只要翻转你的比较就可以了。 – RandyGaul 2013-05-14 18:32:24

+0

就语义而言,调用'v.begin()'和使用'std :: begin(v)'有什么区别?只是好奇。 – 2013-05-14 18:33:09

-1

充分利用()运营商LessA类返回!(a1 < a2)的,并传递它是这样的:

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

是的,但是会按升序排列'v'。我想要降序。 – 2013-05-14 18:28:29

+0

编辑答案。 – 2013-05-14 18:32:20

+2

'!(a1 2013-05-14 18:40:11

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

[我真的不喜欢这个版本。](http://stackoverflow.com/a/9025197/500104) – Xeo 2013-05-14 19:23:30

+0

@Xeo我能说什么,你有30个upvotes为我说的相反。 30 upvoters不能错(c: – 2013-05-14 19:28:53

+1

我不是故意用upvotes作为参数,我的意思是我的答案是为什么我不喜欢这个版本的扩展的解释。对不起,如果它看起来像前者。 – Xeo 2013-05-14 19:41:57

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'; 
} 
+0

如何将'greater'与'A'类型的对象结合使用? – 2013-05-14 19:11:08

+0

@PaulBaltescu您应该重载'operator < '为你的班级'A',然后一切都会自动工作,如果你使用'std :: ' – 2013-05-14 19:12:56

+0

@PaulBaltescu我刚刚做了一个编辑。你可以使用。 – 2013-05-14 19:17:20

相关问题