2013-05-14 72 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

相關問題