Mit Komparator für STL-set
Überprüfen Sie den folgenden code:
string toLowerCase(const string& str) {
string res(str);
int i;
for (i = 0; i < (int) res.size(); i++)
res[i] = (char) tolower(res[i]);
return res;
}
class LeagueComparator
{
public:
bool operator()(const string& s1, const string& s2)
{
return toLowerCase(s1) < toLowerCase(s2);
}
};
int main()
{
set<string, LeagueComparator> leagues;
set<string, LeagueComparator>::iterator iter;
leagues.insert("BLeague");
leagues.insert("aLeague"); //leagues = {"aLeague", "BLeague"}
leagues.insert("ALeague");
for (iter = leagues.begin(); iter != leagues.end(); iter++)
cout << *iter << endl;
return 0;
}
Ausgabe:
aLeague
BLeague
ist schockierend für mich. Ich dachte (und erwarten) die Ausgabe wäre:
aLeague
ALeague
BLeague
Vor der Ausführung von leagues.insert("ALeague");
, die leagues
enthält "aLeague"
und "BLeague"
. Meine Frage ist, während der Ausführung leagues.insert("ALeague");
warum die Maschine behandelt "ALeague" == "aleague"
? Nach meinem Verständnis, gibt es kein element "ALeague"
im leagues
. So "ALeague"
eingefügt werden soll, in leagues
. Der Komparator sollte bestimmen, wo "ALeague"
.
Vielen Dank im Voraus.
PS: Bitte nicht schlagen mich für die Verwendung von C-style cast. 😛 ich bin zu faul zum Typ static_cast
.
Die Tatsache, dass es sich anfühlt, Sie müssen arbeiten, zum ausführen eines C++ - style cast ist einer der Hauptgründe, C++ - Stil-casts vorhanden ist-nämlich, dass Sie sollten es vermeiden, jede Art von casting in C++. In diesem Fall sollten Sie entfernen, werden die Modelle komplett, und verwenden Sie die richtigen Arten statt. I. e. statt
Auch
ONeal: vielen Dank. ich brauche, um verwendet werden zu verwenden
(int) res.size()
entfernen Sie die Besetzung und änderung i
's Art zu sein unsigned
.Auch
i
erklärt werden sollte in der Schleife nicht außerhalb der Schleife. Und in C++, Kleinschreibung sollte wohl einfach anrufen std::transform(str.begin(), str.end(), str.begin(), std::ptr_fun(tolower))
statt zu schreiben eine explizite Schleife.ONeal: vielen Dank. ich brauche, um verwendet werden zu verwenden
transform()
. dass toLowerCase
wurde von mir geschrieben vor vielen Jahren. ich denke, ich wusste nicht, über transform
damals. ich werde zu aktualisieren meinem codebase.InformationsquelleAutor Donotalo | 2010-10-30
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ihre Komparator, Dank der
toLowerCase
sagt, dass"aLeague" == "ALeague"
. Da (nach deinen Komparator)"aLeague" < "ALeague" == false
und"ALeague" < "aLeague" == false
Sie müssen äquivalent sein. Und das einfügen der entsprechenden Elemente in einen Satz tut nichts.Danke, die Bearbeitung meiner post.
InformationsquelleAutor John Calsbeek
Wenn Sie legen alle Wert auf ein gesetzt, wird das Objekt überprüft, ob es bereits diesen Wert enthält. Ihre
LeagueComparator
Objekt vergleichtALeague
mit den beiden anderen Werten ist bereits im set. Es bestimmt, dass Sie den vorhandenen WertaLeague
ist weder größer als noch weniger als die vorgeschlagenen neuen Eintrag (ALeague
), so müssen Sie gleich sein, und so ist es nicht fahren Sie mit dem einfügen. Der Satz bleibt mit nur zwei Elementen. Das ist der springende Punkt bei der Bereitstellung eines Kunden-Vergleich-Objekt, so dass Sie Steuern können, wie das Gerät bestimmt, ob zwei Elemente übereinstimmen.InformationsquelleAutor Rob Kennedy
Angesichts der Komparator Sie, "ALeague" ist in der Tat entspricht "aLeague".
Gegeben zwei Werte, x und y, und eine weniger-als Komparator z:
ONeal: nach STL-doc (habe ich nicht), was sind die Definitionen von
equality
undequivalence
?Gleichheit ist der Vergleich mit einer Gleichheit comparer, oder
operator==
. Gleichwertigkeit ist der Zustand, in dem ein weniger als comparer oderoperator<
gibt false zurück, die entweder für die Bestellung der Argumente, als die hier angegebenen. Konzeptionell, es ist der Unterschied zwischen Gleichheit vergleichbar und weniger als vergleichbare.Siehe effective STL Item #19: Verstehen Sie den Unterschied zwischen Gleichheit und Gleichwertigkeit, für mehr details.
InformationsquelleAutor Eclipse
Ersetzen Sie Ihre
LeagueComparator
mits1 < s2
in allen Fällen. (Weils1 < s2
implizierttoLowerCase(s1) < toLowerCase(s2)
) -1Es ist nicht wahr.
s1="b"
,s2="A"
. Meine Komparator zurückfalse
weilfalse || !true && true = false
.s1 < s2
zurücktrue
.InformationsquelleAutor Alexey Malistov