2008-11-11 36 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()正常。

相关问题