Wie kann ich die map::find-operation mit groß-und Kleinschreibung?
Macht die map::find
Methode unterstützen groß-und Kleinschreibung suchen? Ich habe eine Karte wie folgt:
map<string, vector<string> > directory;
wollen und der unterhalb der Suche auf groß - /Kleinschreibung ignorieren:
directory.find(search_string);
Du musst angemeldet sein, um einen Kommentar abzugeben.
Es nicht standardmäßig. Sie müssen eine benutzerdefinierte Komparator-als drittes argument. Folgendes snippet hilft Ihnen...
Verwenden Sie es wie
std::map< std::string, std::vector<std::string>, ci_less > myMap;
HINWEIS: std::lexicographical_compare hat einige nitty-gritty details. String-Vergleich ist nicht immer einfach, wenn man bedenkt, locales. Sehen diese thread auf c.l.c++, wenn interessiert.
UPDATE: Mit C++11
std::binary_function
ist veraltet und unnötig, denn die Typen werden automatisch abgeleitet.const char&
Komparator-Funktion gibt? Wann macht es überhaupt auslösen? Ist es eine STL-Implementierung detail?std::binary_function
veraltet ist, in C++11 und entfernt in C++17.Hier sind einige andere alternativen, darunter eine, die führt erheblich schneller.
is x < 0
, du hast jetzt einen booleschen Wert, also warum werden Sie dann produziert eine Ganzzahl, die werden dann konvertiert bool entsprechend das return-argument?bool
geben. Ich werde es Bearbeiten.Können Sie instanziieren
std::map
mit drei Parameter: Art der Tasten, der Art der Werte, und Vergleich-Funktion -- ein strict weak ordering (im wesentlichen, eine Funktion oder Funktor, verhält sich wieoperator<
in Bezug auf die Transitivität und anti-Reflexivität), das Ihren wünschen entspricht. Legen Sie den Dritten parameter das zu tun", groß- /Kleinschreibung nicht weniger-als" (z.B. durch eine<
auf die kleingeschrieben werden strings es ist Vergleich) und Sie haben den "groß- /Kleinschreibung Karte", die Sie sich wünschen!Benutze ich folgende:
In Fall, dass Sie nicht möchten, berühren Sie den map-Typ (halten Sie ursprüngliche Einfachheit und Effizienz), aber nicht dagegen, mit einem langsameren groß- /Kleinschreibung zu suchen-Funktion (O(N)):
PS: Vielleicht war es Roger Pate ' s Idee, aber nicht sicher, da manche details waren ein wenig off (std::search?, direkte string-Vergleicher?)
Nein, Sie können nicht tun, mit
find
wie in diesem Fall gibt es mehrere übereinstimmungen. Zum Beispiel, während Sie können Sie etwas getan haben, wiemap["A"] = 1
undmap["a"] = 2
und jetzt, wenn Sie möchten, eine groß-und Kleinschreibungmap.find("a")
was ist die zu erwartende Rendite Wert? Der einfachste Weg, um dieses Problem zu lösen wäre, legen Sie die Zeichenfolge in die Karte nur in einem Fall (entweder groß-oder kleingeschrieben) und dann mit dem gleichen Fall, während Sie das finden.std::map
unterstützt, sondern einen index, der entweder groß-und Kleinschreibung der groß- / Kleinschreibung, aber nicht beide. Von dort aus ist es eine einfache Verknüpfung zuboost::multi_index
, die nicht die Unterstützung einer zweiten index.Vergleichen element in der map-Vorlage standardmäßig einen binären Vergleich der Klasse "weniger". Blick auf die Implementierung:
http://www.cplusplus.com/reference/std/functional/less/
Können Sie wahrscheinlich erstellen Sie Ihre eigene Klasse, abgeleitet von binary_function (die übergeordnete Klasse weniger) und das gleiche tun Vergleich ohne groß-und Kleinschreibung.
Getestet:
Für C++11 und darüber hinaus:
Implementieren, std::less-Funktion und vergleichen Sie durch ändern sowohl der gleiche Fall.
Möchte ich eine kurze Lösung ohne Verwendung von Boost-oder-Vorlagen. Da C++11 Sie können auch eine lambda-Ausdruck als benutzerdefinierte Komparator-zu Ihrer Karte. Für einen POSIX-kompatiblen system, die Lösung könnte wie folgt Aussehen:
Code auf Ideone
Für Fenster,
strcasecmp()
nicht vorhanden, aber Sie können_stricmp()
statt:Hinweis: Abhängig von Ihrem system und Sie, ob diese Unicode unterstützen oder nicht, müssen Sie möglicherweise die strings vergleichen in einer anderen Weise. Dieses Q&A gibt einen guten start.