2008-11-11 37 views
104

如果我有對的載體:如何根據對中的第二個元素對對的向量進行排序?

std::vector<std::pair<int, int> > vec; 

有沒有簡便的方法來進行排序基於對的第二個元素遞增的順序列表?

我知道我可以寫一個小函數對象,將做的工作,但有使用STLstd::less的現有部分直接做工作的方法嗎?

編輯:我明白,我可以編寫一個單獨的函數或類傳遞給第三個參數進行排序。問題是我是否可以用標準的東西來構建它。我真的東西,看起來像:

std::sort(vec.begin(), vec.end(), std::something_magic<int, int, std::less>()); 
+1

C++沒有lamdas,所以你不能做到你想要的,你需要創建一個單獨的函數/仿函數。這可以是一個單線,所以它真的不應該是一個大問題。 – 2008-11-11 03:44:43

+0

這裏是一個例子:
[std :: sort in pairs of pairs](http://www.codeguru.com/forum/archive/index.php/t-325645.html) – LeppyR64 2008-11-11 02:46:48

回答

69

您可以使用升壓像這樣:

std::sort(a.begin(), a.end(), 
      boost::bind(&std::pair<int, int>::second, _1) < 
      boost::bind(&std::pair<int, int>::second, _2)); 

我不知道一個標準的方式來做到這一點同樣簡短,但你可以抓住boost::bind這是所有包含標題。

170

編輯:使用C++ 14,最好的解決方案是很容易寫的感謝到現在可以具有auto類型的參數的lambda。 這是我目前最喜歡的解決方案

std::sort(v.begin(), v.end(), [](auto &left, auto &right) { 
    return left.second < right.second; 
}); 

只需使用一個自定義的比較(這是一個可選的第三個參數來std::sort

struct sort_pred { 
    bool operator()(const std::pair<int,int> &left, const std::pair<int,int> &right) { 
     return left.second < right.second; 
    } 
}; 

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

如果您使用的是C++編譯器11 ,你可以使用lambdas寫下相同的文字:

std::sort(v.begin(), v.end(), [](const std::pair<int,int> &left, const std::pair<int,int> &right) { 
    return left.second < right.second; 
}); 

編輯:響應您的編輯你的問題,這裏的一些想法... 如果你真的勇於創新,能夠重複使用這個概念有很多,只是做一個模板:

template <class T1, class T2, class Pred = std::less<T2> > 
struct sort_pair_second { 
    bool operator()(const std::pair<T1,T2>&left, const std::pair<T1,T2>&right) { 
     Pred p; 
     return p(left.second, right.second); 
    } 
}; 

那麼你也可以這樣做:

std::sort(v.begin(), v.end(), sort_pair_second<int, int>()); 

甚至

std::sort(v.begin(), v.end(), sort_pair_second<int, int, std::greater<int> >()); 

雖然說實話,這是所有有點矯枉過正,只寫了3線功能,並用它做:-P

+59

+1供使用的標準STL而不是Boost! – ragebiswas 2013-02-24 16:03:25

+0

請記住,這與`pair `中的`operator <`不同。默認的比較器使用* both * first和second元素(在第一個元素相等的情況下)。這裏只使用第二個。 – Googol 2014-12-04 23:11:55

+0

@Googol:這正是OP所要求的...他說: `「是否有簡單的方法來根據對的第二個元素以遞增的順序對列表進行排序?」 – 2014-12-05 18:42:29

5

對於一些可重複使用:

template<template <typename> class P = std::less > 
struct compare_pair_second { 
    template<class T1, class T2> bool operator()(const std::pair<T1, T2>& left, const std::pair<T1, T2>& right) { 
     return P<T2>()(left.second, right.second); 
    } 
}; 

你可以使用它作爲

std::sort(foo.begin(), foo.end(), compare_pair_second<>()); 

std::sort(foo.begin(), foo.end(), compare_pair_second<std::less>()); 
29

用C++ 0x中,我們可以使用lambda函數:

using namespace std; 
vector<pair<int, int>> v; 
     . 
     . 
sort(v.begin(), v.end(), 
    [](const pair<int, int>& lhs, const pair<int, int>& rhs) { 
      return lhs.second < rhs.second; }); 

在此示例中,隱式推導返回類型bool

LAMBDA返回類型

當λ-功能有一個單一的語句,這是一個返回語句,編譯器可以推斷返回類型。從C++ 11,§5.1.2/ 4:

...

  • 如果化合物語句的形式{ return expression ; }返回的表達後的類型的左值到右值轉換(4.1),數組到指針的轉換(4.2)和函數到指針的轉換(4.3);
  • 否則,void

要明確指定返回類型使用表單[]() -> Type { },像:

sort(v.begin(), v.end(), 
    [](const pair<int, int>& lhs, const pair<int, int>& rhs) -> bool { 
      if (lhs.second == 0) 
       return true; 
      return lhs.second < rhs.second; }); 
19

它相當簡單 您使用排序功能的算法,並添加自己的比較功能

vector< pair<int,int > > v; 
sort(v.begin(),v.end(),myComparison); 

現在您必須根據第二個選擇 進行比較,因此請聲明您的「myComp埃裏森」爲

bool myComparison(const pair<int,int> &a,const pair<int,int> &b) 
{ 
     return a.second<b.second; 
} 
-1

嘗試更換對的元素,因此你可以使用std::sort()正常。

相關問題