2017-12-08 8 views
0

Kein Thema löste mein Problem des Vergleichens von Strukturen als Schlüsselzuordnung in C++.So lösen Sie das Vergleichen von Strukturen als Schlüsselzuordnung C++

Structs folgenden Code:

struct XYZ{ 
    int x, y, z; 
} 

struct XYZComp{ 
    bool operator()(const XYZ& l, const XYZ& r) 
    { 
    return ((l.x==r.x)&&(l.y==r.y)&&(l.z==r.z)); 
    } 
} 

Haupt sieht aus wie

int main() 
{ 
    map<XYZ, int, XYZComp> m; 
    m.insert(std::make_pair<XYZ,int>({1,2,3}, 1)); //ok 

    map<XYZ, int, XYZComp>::iterator it = m.find({1,0,3}); 
    if(it!=m.end()) 
    { 
    std::cout<<"Key exists in map"; 
    } 
    else 
    { 
    m.insert(std::make_pair<XYZ,int>({1,0,3}, 1)); 
    //never come here 
    //compiler thinks key already exists in map 
    } 

return 0; 
} 

ich ohne XYZComparer nur versucht, aber es funktioniert immer noch nicht.

Wie zu lösen, diese Strukturen XYZ zu vergleichen, während ich das vorhandene Element in der Karte versuche.

Edit: Compiler denkt, Strukturen sind die gleichen, wenn mindestens eine Zahl korrekt ist.

+0

nicht hilfreich. Ich könnte es so lassen und lassen Sie heraus, warum (was genauso hilfreich ist) oder ich könnte erklären, warum es nicht hilfreich ist, Ihnen die Zeit und Mühe zu sparen, es zu suchen ... Ja - wenn es nicht funktioniert, Sagen Sie, was Sie bekommen und was Sie erwartet haben, damit die Leute nicht selbst versuchen müssen, es selbst auszuarbeiten! – UKMonkey

Antwort

0

Der Komparator std::set und std::map sollte als <, nicht == funktionieren. Der binäre Suchbaum muss nicht nur wissen, ob Objekte gleich sind; es muss ihnen eine Reihenfolge geben, weil die Datenstruktur sortiert ist. Überladen Sie den Operator < für Ihre Objekte.

Die Objekte werden als gleich betrachtet, wenn !comp(a, b) && !comp(b, a). (Source)

Wenn Sie < überlasten, müssen Sie nicht explizit den Komparator an den Containertyp liefern, da der Standard Komparator ist std::less, die den < Betreiber wickelt.

0

Die std::map verwendet <, um Artikel zu bestellen. Daher muss Ihr struct XYZComp einen benutzerdefinierten operator < liefern.

Eine sehr einfache Lösung ist std::tie zu verwenden:

#include <tuple> 
//.. 
struct XYZComp 
{ 
    int x,y,z; 
    bool operator < (const XYZComp& xyz) 
    { 
     return std::tie(x, y, z) < std::tie(xyz.x, xyz.y, xyz.z); 
    } 
    //... 
}; 

Die std::tie lexikographische Ordnung auf Ihre Struktur der Elemente einführt.

Sie könnten das gleiche tun durch abstürzende die < Vergleiche, aber dann der Code länger und ist einfacher, einen Fehler zu machen: „, aber es funktioniert immer noch nicht“

struct XYZComp 
{ 
    int x,y,z; 
    bool operator < (const XYZComp& xyz) 
    { 
     if (x < xyz.x) 
     return true; 
     if (x == xyz.x && y < xyz.y) 
     return true; 
     if (x == xyz.x && y == xyz.y) 
      return z < xyz.z; 
     return false; 
    } 
    //... 
};