쌍의 두 번째 요소를 기준으로 쌍의 벡터를 어떻게 정렬합니까?
문제
벡터 쌍이있는 경우 :
std::vector<std::pair<int, int> > vec;
쌍의 두 번째 요소를 기반으로 순서가 높아지는 목록을 쉽게 정렬 할 수있는 방법이 있습니까?
작업을 수행 할 작은 기능 객체를 쓸 수는 있지만 기존 부분을 사용할 수있는 방법이 있습니다. STL 그리고 std::less
일을 직접하려면?
편집 : 세 번째 인수로 전달하기 위해 별도의 기능이나 클래스를 작성할 수 있다는 것을 이해합니다. 문제는 표준 물건으로 구축 할 수 있는지 여부입니다. 나는 정말로 보이는 것 : 나는 다음과 같다.
std::sort(vec.begin(), vec.end(), std::something_magic<int, int, std::less>());
해결책
편집하다: C ++ 14를 사용하면 최상의 솔루션은 이제 유형의 매개 변수를 가질 수있는 람다 덕분에 글을 쓰는 것이 매우 쉽습니다. auto
. 이것은 내가 가장 좋아하는 솔루션입니다
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 줄 기능을 작성하고 다음과 같이 수행하십시오.
다른 팁
다음과 같이 부스트를 사용할 수 있습니다.
std::sort(a.begin(), a.end(),
boost::bind(&std::pair<int, int>::second, _1) <
boost::bind(&std::pair<int, int>::second, _2));
나는 이것을 똑같이 짧고 간결하게하는 표준 방법을 모르겠지만, 당신은 잡을 수 있습니다. boost::bind
모두 헤더로 구성되어 있습니다.
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-Function에 단일 명세서가 있고 이는 리턴 진술 인 경우 컴파일러는 리턴 유형을 추론 할 수 있습니다. C ++ 11, §5.1.2/4 :
...
- 화합물 진술이 형태 인 경우
{ return expression ; }
lvalue-to-rvalue 변환 (4.1), 배열-포인터 변환 (4.2) 및 함수-포인터 변환 (4.3) 후 반환 된 표현의 유형;- 그렇지 않으면,
void
.
리턴 유형을 명시 적으로 지정하려면 양식을 사용하십시오 []() -> Type { }
, in : :
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; } );
알고리즘에서 정렬 함수를 사용하고 자신의 비교 기능을 추가하십시오.
vector< pair<int,int > > v;
sort(v.begin(),v.end(),myComparison);
이제 두 번째 선택에 따라 비교를해야하므로 "MyComparison"을 다음과 같이 선언합니다.
bool myComparison(const pair<int,int> &a,const pair<int,int> &b)
{
return a.second<b.second;
}
재사용 할 수있는 것 :
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>());
비 표준에 의존해야합니다 Select2nd
사용할 수 있도록 쌍의 요소를 교환 해보세요. std::sort()
정상적으로.