typedef map<string, string> myMap;
Beim Einfügen eines neuen Paares in myMap
wird der Schlüssel string
zum Vergleichen durch einen eigenen Zeichenfolgenkomparator verwendet. Ist es möglich, diesen Komparator zu überschreiben? Zum Beispiel möchte ich den Schlüssel string
nach seiner Länge vergleichen, nicht nach dem Alphabet. Oder gibt es eine andere Möglichkeit, die Karte zu sortieren?
std::map<std::string, std::string> myMap(cmpByStringLength());
cmpByStringLength
keine Instanz von iststd::less<std::string>
. Für eine allgemeine Karte, für die ein beliebiger Komparator im Konstruktor festgelegt werden kann, benötigen Sie etwastd::map<std::string, std::string, std::function<bool(const std::string &, const std::string &)>> myMap(cmpByStringLength);
Seit C ++ 11 können Sie auch einen Lambda-Ausdruck verwenden, anstatt eine Komparatorstruktur zu definieren:
auto comp = [](const string& a, const string& b) { return a.length() < b.length(); }; map<string, string, decltype(comp)> my_map(comp); my_map["1"] = "a"; my_map["three"] = "b"; my_map["two"] = "c"; my_map["fouuur"] = "d"; for(auto const &kv : my_map) cout << kv.first << endl;
Ausgabe:
Ich möchte die letzte Anmerkung von Georgs Antwort wiederholen: Wenn Sie nach Länge vergleichen, können Sie nur eine Zeichenfolge jeder Länge in der Karte als Schlüssel haben.
Code auf Ideone
quelle
Ja, der dritte Vorlagenparameter auf
map
gibt den Komparator an, bei dem es sich um ein binäres Prädikat handelt. Beispiel:struct ByLength : public std::binary_function<string, string, bool> { bool operator()(const string& lhs, const string& rhs) const { return lhs.length() < rhs.length(); } }; int main() { typedef map<string, string, ByLength> lenmap; lenmap mymap; mymap["one"] = "one"; mymap["a"] = "a"; mymap["fewbahr"] = "foobar"; for( lenmap::const_iterator it = mymap.begin(), end = mymap.end(); it != end; ++it ) cout << it->first << "\n"; }
quelle
std::binary_function
? Wird es gebraucht?std::binary_function
wird in c ++ 17 entfernt, daher könnte diese Antwort möglicherweise aktualisiert werden.Geben Sie den Typ des Zeigers auf Ihre Vergleichsfunktion als dritten Typ in der Karte an und geben Sie den Funktionszeiger für den Kartenkonstruktor an:
map<keyType, valueType, typeOfPointerToFunction> mapName(pointerToComparisonFunction);
Schauen Sie sich das folgende Beispiel an, um eine Vergleichsfunktion für a bereitzustellen
map
, mitvector
Iterator als Schlüssel undint
als Wert.#include "headers.h" bool int_vector_iter_comp(const vector<int>::iterator iter1, const vector<int>::iterator iter2) { return *iter1 < *iter2; } int main() { // Without providing custom comparison function map<vector<int>::iterator, int> default_comparison; // Providing custom comparison function // Basic version map<vector<int>::iterator, int, bool (*)(const vector<int>::iterator iter1, const vector<int>::iterator iter2)> basic(int_vector_iter_comp); // use decltype map<vector<int>::iterator, int, decltype(int_vector_iter_comp)*> with_decltype(&int_vector_iter_comp); // Use type alias or using typedef bool my_predicate(const vector<int>::iterator iter1, const vector<int>::iterator iter2); map<vector<int>::iterator, int, my_predicate*> with_typedef(&int_vector_iter_comp); using my_predicate_pointer_type = bool (*)(const vector<int>::iterator iter1, const vector<int>::iterator iter2); map<vector<int>::iterator, int, my_predicate_pointer_type> with_using(&int_vector_iter_comp); // Testing vector<int> v = {1, 2, 3}; default_comparison.insert(pair<vector<int>::iterator, int>({v.end(), 0})); default_comparison.insert(pair<vector<int>::iterator, int>({v.begin(), 0})); default_comparison.insert(pair<vector<int>::iterator, int>({v.begin(), 1})); default_comparison.insert(pair<vector<int>::iterator, int>({v.begin() + 1, 1})); cout << "size: " << default_comparison.size() << endl; for (auto& p : default_comparison) { cout << *(p.first) << ": " << p.second << endl; } basic.insert(pair<vector<int>::iterator, int>({v.end(), 0})); basic.insert(pair<vector<int>::iterator, int>({v.begin(), 0})); basic.insert(pair<vector<int>::iterator, int>({v.begin(), 1})); basic.insert(pair<vector<int>::iterator, int>({v.begin() + 1, 1})); cout << "size: " << basic.size() << endl; for (auto& p : basic) { cout << *(p.first) << ": " << p.second << endl; } with_decltype.insert(pair<vector<int>::iterator, int>({v.end(), 0})); with_decltype.insert(pair<vector<int>::iterator, int>({v.begin(), 0})); with_decltype.insert(pair<vector<int>::iterator, int>({v.begin(), 1})); with_decltype.insert(pair<vector<int>::iterator, int>({v.begin() + 1, 1})); cout << "size: " << with_decltype.size() << endl; for (auto& p : with_decltype) { cout << *(p.first) << ": " << p.second << endl; } with_typedef.insert(pair<vector<int>::iterator, int>({v.end(), 0})); with_typedef.insert(pair<vector<int>::iterator, int>({v.begin(), 0})); with_typedef.insert(pair<vector<int>::iterator, int>({v.begin(), 1})); with_typedef.insert(pair<vector<int>::iterator, int>({v.begin() + 1, 1})); cout << "size: " << with_typedef.size() << endl; for (auto& p : with_typedef) { cout << *(p.first) << ": " << p.second << endl; } }
quelle