suchen in Sets mit eigener Klasse
-
Hallo...
vielleicht kann mir hier jemand helfen.
Ich habe eine Klasse "Schlüssel", welche sich aus 3 Elementen zusammensetzt
Name1,Name2,Wertdiese Klasse Schlüssel speicher ich in einen Set, um die Elemente zu sortieren. Hierfür habe ich schon den <operator überladen.
Nun möchte ich gern in meinen abgespeicherten Schlüssel auch suchen.
Hierfür will ich einmal nach Schlüssel suchen, welche nur mit Name1 anfangen oder auch nach Schlüsseln suchen, welche mit Name1 und Name2 anfangen und natürlich auch mit Name1, Name2, und Wert.Zuerst dachte ich ok, überlade ich auch den == operator, aber dann kann ich damit ja nur einen Fall abdecken... was kann ich denn da noch tun?
Kann man den find operator auch überladen?
Dankeschön
Viele Grüße
Julia
-
Zunächst einmal wirst du nicht set::find benutzen können. Dieses ist bereits mit deinem operator< verknüpft und benutzt ausschließlich diesen.
Es gibt auch noch std::find, diese benutzt den Operator==, so dass du dir da einen eigenen definieren kannst. Weiterhin kannst du dies mit find_if noch verfeinern. Das ganze wäre dann aber eine sequentielle Suche über das ganze set, d.h. alle Vorteile von set gingen bei der Suche verloren.
Was vielleicht möglich wäre: Ist es möglich, eine Klasse als halbfertig zu markieren? Also dass du z.B. dem Schlüssel 2 einen besonderen Wert gibst oder einen bool setzt, dass danach nicht sortiert werden soll? Dein Operator< muss dies dann beachten. Und du solltest dann ein multiset nehmen.
-
Danke für die schnelle Antwort... die sequentielle Suche wollte ich eben vermeiden, sonst kann ich ja einfahc einen Iterator darüber laufen lassen

Ob ich in der Klasse irgendwo was makieren kann, bin ich mir nicht so sicher.. aber trotzdem danke

-
Das Stichwort dafür lautet: Functor
Du kannst anstatt set::find() die freie Funktion std::find_if(...) dafür benutzen, s. http://www.cplusplus.com/reference/algorithm/find_if/
Du mußt dann nur entsprechend verschiedene Vergleichsfunktionen implementieren und diese dann als 3. Parameter angeben.
P.S. theta hatte dir doch schon dieselbe Antwort gegeben: http://www.c-plusplus.net/forum/p2018763#2018763 ...
Noch ein P.S.: Wenn du die sequentielle Suche vermeiden willst, dann benötigst du eine andere Datenstruktur, z.B. std::map und zwar für jede deiner Suchmöglichkeiten je eine.
-
aber ich dachte das geht dann nicht für sets? sorry war mir gar nicht so bewusst, dass ich ja schon eine ähnliche Frage gestellt habe.
-
Ich dachte an so etwas:
#include<iostream> #include<set> using namespace std; class foo { int wert1; double wert2; bool sort_wert2; public: explicit foo(int wert1): wert1(wert1), sort_wert2(false){} foo(int wert1, double wert2): wert1(wert1), wert2(wert2), sort_wert2(true){} friend bool operator<(const foo& a, const foo& b) { if (a.wert1<b.wert1) return true; if ((a.wert1==b.wert1) && a.sort_wert2 && b.sort_wert2) if (a.wert2<b.wert2) return true; return false; } friend ostream& operator<<(ostream &out, const foo& a) { out<<'('<<a.wert1<<','<<a.wert2<<')'; return out; } }; int main() { multiset<foo> foos; foos.insert(foo(3,2)); foos.insert(foo(3,3)); foos.insert(foo(3,4)); foos.insert(foo(1,2)); foos.insert(foo(1,3)); foos.insert(foo(1,4)); foos.insert(foo(2,4)); foos.insert(foo(2,3)); foos.insert(foo(2,2)); cout<<"In sortierter Reihenfolge:\n"; for (multiset<foo>::iterator it=foos.begin(); it!=foos.end(); ++it) cout<<(*it)<<'\n'; cout<<'\n'; cout<<"Ist (3,1) enthalten?\n"; if (foos.count(foo(3,1))) cout <<"Ja\n\n"; else cout <<"Nein\n\n"; cout<<"Ist (3,2) enthalten?\n"; if (foos.count(foo(3,2))) cout <<"Ja\n\n"; else cout <<"Nein\n\n"; cout<<"Sind (4,*) enthalten?\n"; if (foos.count(foo(4))) cout <<"Ja, und zwar "<< foos.count(foo(4)) <<" Stück \n\n"; else cout <<"Nein\n\n"; cout<<"Sind (2,*) enthalten?\n"; if (foos.count(foo(2))) cout <<"Ja, und zwar "<< foos.count(foo(2)) <<" Stück \n\n"; else cout <<"Nein\n\n"; cout<<"Alle (2,*):\n"; pair<multiset<foo>::iterator, multiset<foo>::iterator> ret = foos.equal_range(foo(2)); for (multiset<foo>::iterator it=ret.first; it!=ret.second; ++it) cout<<(*it)<<'\n'; }