2012-03-24 8 views
3

Ich versuche, eine pair<int,int> zu einem Satz hinzuzufügen. Wenn ein Paar die gleichen zwei Werte wie ein anderes in der Menge teilt, sollte es nicht eingefügt werden.Paar gleich Operatorüberlastung für das Einfügen in Satz

Hier ist mein nicht-funktionierenden Code:

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)); 
} 

Im Moment das (4,1) Paar wird hinzugefügt, obwohl es bereits ein (1,4) Paar. Der endgültige Inhalt des Satzes ist:

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

und ich mag es

(1 3) 
(1 4) 

Ich habe versucht, sein habe Haltepunkte in der überladenen Methode setzen, aber sie nie erreicht bekommen. Was habe ich falsch gemacht?

Antwort

0

Der Vergleich bestimmen sollte, wenn erstes Element kleiner als der zweite Punkt ist. So sollte es so aussehen:

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; 
    } 
} 

Jetzt gibt es die gewünschte Ausgabe:

1,3 
1,4 

Werfen Sie einen Blick auf die online demo.

Beachten Sie, dass die Funktion vergleichen folgt: Strict weak ordering

+1

Funktioniert perfekt, danke – Petwoip

+0

@Nawaz können Sie einen ähnlichen Ansatz für die Überladung akashchandrakar

+0

@aksam bieten: Versuchen Sie sich zuerst. Dann lassen Sie mich wissen, was Sie bereits versucht haben. Vielleicht, dann würde ich helfen. – Nawaz

2

Sie müssen eine Vergleichsfunktion bereitstellen, damit ein Element weniger als das andere Element angezeigt wird, und nicht, um festzustellen, ob sie identisch sind. Hier ist ein komplettes Beispiel:

#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"; 
    } 
} 

Ausgang:

1,3 
1,4 
+0

wurde um mit maßgeschneiderten Sets spielen ... Nur frage mich, was ist der Unterschied zwischen der Methode, die Sie oben geschrieben, und das Verfahren auf cplusplus Website? Ich finde Ihren Code ein wenig leichter zu verstehen, aber immer noch nicht sehr klar zum Beispiel das '(*)' in der Typedef. :) – Juto

+0

@Juto: Ich habe ein Typedef hinzugefügt, um das hoffentlich ein wenig klarer zu machen. Lass es mich wissen, wenn etwas noch nicht klar ist. Können Sie mir einen Link zu der Methode auf der cplusplus-Website geben, über die Sie sprechen? –

3

Sets basieren auf operator< (Ordnungs/Äquivalenzbeziehung), nicht operator== (das ist eine Gleichheitsbeziehung).

das, was zu tun, dass Sie zu tun versuchen, einen Komparator benutzerdefinierten verwenden:

#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); 
} 
Verwandte Themen