2012-03-24 2 views
3

집합에 pair<int,int>을 추가하려고합니다. 쌍이 세트의 다른 두 값과 동일한 두 값을 공유하면 삽입되지 않아야합니다.집합에 삽입하기위한 쌍등호 연산자 오버로드

가 여기 내 비 작동 코드입니다 : 순간

typedef std::pair<int, int> PairInt; 

template<> 
bool std::operator==(const PairInt& l, const PairInt& r) 
{ 
    return (l.first == r.first && l.second == r.second) || 
      (l.first == r.second && l.second == r.first); 
} 

int main() 
{ 
    std::set<PairInt> intSet; 
    intSet.insert(PairInt(1,3)); 
    intSet.insert(PairInt(1,4)); 
    intSet.insert(PairInt(1,4)); 
    intSet.insert(PairInt(4,1)); 
} 

의 (4,1) 쌍은 이미 (1,4) 쌍이 경우에도 추가됩니다. 세트의 마지막 내용은 다음과 같습니다

(1 3) 
(1 4) 
(4 1) 

그리고 나는 내가 오버로드 된 방법에 중단 점을 넣어 시도했습니다

(1 3) 
(1 4) 

되고 싶어하지만, 그들은 결코 도달하지 얻을. 나는 무엇을 잘못 했는가?

답변

0

첫 번째 항목이 두 번째 항목보다 작은 경우 결정해야한다 비교합니다. 그래서 다음과 같이해야합니다 :

1,3 
1,4 

online demo에서보세요 :

namspace std 
{ 
    template<> 
    bool operator < (const PairInt& l, const PairInt& r) 
    { 
    //swap only if they're unequal to avoid infinite recursion 
    if (l.first != l.second) 
    { 
     //swap elements, considering your special case 
      if (l.first == r.second && l.second == r.first) 
      return l < PairInt(r.second, r.first); //call again! 
    } 

    //actual comparison is done here 
    if (l.first != r.first) 
     return l.first < r.first; 
    else 
     return l.second < r.second; 
    } 
} 

는 이제 원하는 출력을 제공합니다. (가) 기능을 비교하는 것이

참고 다음 : Strict weak ordering

+1

완벽하게 작동합니다. 감사합니다. – Petwoip

+0

@Nawaz는 3 가지 요소가 포함 된 strucutre에 대한 오버로드에 대해 비슷한 접근 방식을 제공 할 수 있습니다. – akashchandrakar

+0

@aksam : 먼저 시도해보십시오. 그럼 이미 시도한 것을 알려주세요. 어쩌면 내가 도울거야. – Nawaz

2

하나의 항목을 보는 것이 다른 것보다 작 으면 비교 기능을 제공해야합니다. 비교 기능이 동일하지 않은지 비교하기 위해 비교 기능을 제공해야합니다. 여기에 완벽한 예입니다

#include <utility> 
#include <algorithm> 
#include <set> 
#include <iostream> 

typedef std::pair<int, int> PairInt; 
typedef bool Compare(const PairInt &,const PairInt &); 

bool compare(const PairInt &l,const PairInt &r) 
{ 
    int lfirst = std::min(l.first,l.second); 
    int rfirst = std::min(r.first,r.second); 
    if (lfirst<rfirst) return true; 
    if (rfirst<lfirst) return false; 
    return std::max(l.first,l.second)<std::max(r.first,r.second); 
} 

int main() 
{ 
    typedef std::set<PairInt,Compare*> IntSet; 
    IntSet intSet(compare); 
    intSet.insert(PairInt(1,3)); 
    intSet.insert(PairInt(1,4)); 
    intSet.insert(PairInt(1,4)); 
    intSet.insert(PairInt(4,1)); 
    for (IntSet::const_iterator i=intSet.begin(); i!=intSet.end(); ++i) { 
    std::cerr << i->first << "," << i->second << "\n"; 
    } 
} 

출력 :

1,3 
1,4 
+0

당신이 위의 게시 방법 및 CPLUSPLUS 웹 사이트에서 방법의 차이점은 무엇입니까, 그냥 궁금 ... 사용자 정의 세트 장난이 되었습니까? 나는 당신의 코드를 조금 더 이해하기 쉽지만, typedef의'(*)'에 대해서는 아직 명확하지 않다. :) – Juto

+0

@ Juno : 좀 더 명확하게하기 위해 typedef를 추가했습니다. 뭔가 명확하지 않은 경우 알려주십시오. 당신이 말하는 cplusplus 웹 사이트의 방법에 대한 링크를 줄 수 있습니까? –

3

설정이 operator< (AN 주문/등가 관계)를 기반으로, (동등 관계)하지 operator==.

은 당신이하려고하는 일을 수행하려면, 사용자 정의 비교를 사용

#include <set> 
#include <utility> 
#include <cassert> 
typedef std::pair<int, int> PairInt; 
PairInt normalize(const PairInt& p) { 
    return p.second < p.first ? PairInt(p.second, p.first) : p; 
} 
struct Comparator { 
    bool operator()(const PairInt& l, const PairInt& r) const { 
     //Compare canonical forms of l and r. 
     return normalize(l) < normalize(r); 
    } 
}; 

int main() 
{ 
    std::set<PairInt, Comparator> intSet; 
    intSet.insert(PairInt(1,3)); 
    intSet.insert(PairInt(1,4)); 
    intSet.insert(PairInt(1,4)); 
    intSet.insert(PairInt(4,1)); 
    assert(intSet.size() == 2); 
}