쌍의 두 번째 요소를 기준으로 쌍의 벡터를 어떻게 정렬합니까?

StackOverflow https://stackoverflow.com/questions/279854

  •  07-07-2019
  •  | 
  •  

문제

벡터 쌍이있는 경우 :

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() 정상적으로.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top