Was ist der Unterschied zwischen std :: multimap <Schlüssel, Wert> und std :: map <Schlüssel, std :: set <Wert>>

85

Ich fand heraus, dass sie einen Schlüssel und mehrere Werte haben, was einzigartig ist.

大 宝剑
quelle

Antworten:

51

Die Multimap speichert Paare von (Schlüssel, Wert), wobei sowohl Schlüssel als auch Wert mehrmals vorkommen können.

Der map<key, set<value>>Wert wird nur einmal für einen bestimmten Schlüssel gespeichert. Dazu muss es in der Lage sein, die Werte zu vergleichen, nicht nur die Schlüssel.

Es hängt von Ihrer Anwendung ab, ob die vergleichbaren Werte gleichwertig sind oder ob Sie sie trotzdem separat speichern möchten. Vielleicht enthalten sie Felder, die unterschiedlich sind, aber nicht am Vergleich für die Menge teilnehmen.

Bo Persson
quelle
5
Ein std :: multimap <Schlüssel, Wert> ist also wie ein std :: map <Schlüssel, std :: multiset <Wert>>. Der Unterschied zwischen ihnen besteht darin, dass die Werte des späteren sortiert sind. Ist das richtig?
宝剑 宝剑
2
Nein, std::multimap<key, value>lässt zu , dass derselbe Schlüssel mehrmals angezeigt wird std::map<key, whatever>, während die Eindeutigkeit von erforderlich ist key.
Yixing Liu
73

A std::mapist ein assoziativer Container, mit dem Sie Ihrem Typwert einen eindeutigen Schlüssel zuordnen können. Beispielsweise,

void someFunction()
{
    typedef std::map<std::string, int> MapType;
    MapType myMap;

    // insertion
    myMap.insert(MapType::value_type("test", 42));
    myMap.insert(MapType::value_type("other-test", 0));

    // search
    auto it = myMap.find("test");
    if (it != myMap.end())
        std::cout << "value for " << it->first << " is " << it->second << std::endl;
    else
        std::cout << "value not found" << std::endl;
}

A std::multimapist gleich a std::map, aber Ihre Schlüssel sind nicht mehr eindeutig. Daher können Sie eine Reihe von Artikeln finden, anstatt nur einen einzigen Artikel zu finden. Beispielsweise,

void someFunction()
{
    typedef std::multimap<std::string, int> MapType;
    MapType myMap;

    // insertion
    myMap.insert(MapType::value_type("test", 42));
    myMap.insert(MapType::value_type("test", 45));
    myMap.insert(MapType::value_type("other-test", 0));

    // search
    std::pair<auto first, auto second> range = myMap.equal_range("test");
    for (auto it = range.first; it != range.second; ++it)
        std::cout << "value for " << it->first << " can be " << it->second << std::endl;
}

Das std::setist wie ein std::map, speichert jedoch keinen Schlüssel, der einem Wert zugeordnet ist. Es speichert nur den Schlüsseltyp und stellt sicher, dass er innerhalb des Satzes eindeutig ist.

Sie haben auch die std::multiset, die dem gleichen Muster folgt.

Alle diese Container bieten einen O-Zugriff (log (n)) mit ihrem find / equal_range.

typedef
quelle
5
In der Multimap-Funktion funktioniert diese Zeile std::pair<auto first, auto second> range = myMap.equal_range("test");nicht, weil error: 'auto' not allowed in template argument. Verwenden Sie const auto range = myMap.equal_range("test")stattdessen.
Vancexu
2
Kartentyp? Sollte es nicht MapType in Zeile 4 sein?
lolololol ol
Ich
bin mir
1
ahah, cppbuzz kratzt StackOverflow oder was? Ich habe diese Antwort selbst vor Jahren geschrieben, als ich noch täglich in c ++ programmierte. Und es gibt tatsächlich eine Tippfehlerzeile 4, danke @lololololol
typedef
1
(und ihr Kopieren / Einfügen ist fehlgeschlagen, sie zeigen nicht einmal Typen in der Vorlage std :: map-Deklaration an: std :: map <std :: string, int>)
typedef
13
map::insert

Da mapContainer keine doppelten Schlüsselwerte zulassen, prüft die Einfügeoperation für jedes eingefügte Element, ob bereits ein anderes Element mit demselben Schlüsselwert im Container vorhanden ist. In diesem Fall wird das Element nicht eingefügt und sein zugeordneter Wert wird in keiner Weise geändert.

andererseits

multimap::insert 

kann beliebig viele Elemente mit demselben Schlüssel einfügen.

http://www.cplusplus.com/reference/stl/map/
http://www.cplusplus.com/reference/stl/multimap/

Luka Rahne
quelle
Guter Link sowohl zum Unterschied als auch zur internen Funktionsweise. Link
Rndp13
10

Letzteres erfordert, dass die Werte geordnet werden können (entweder über operator<oder eine Vergleichsfunktion), Ersteres nicht.

Björn Pollex
quelle
Es scheint, dass Operator <auf Karte oder Multimap gleich funktioniert. en.cppreference.com/w/cpp/container/map/operator_cmp
Johnbakers
Ja, aber meine Antwort bezog sich auf die Reihenfolge der Werte. Angenommen, Sie haben einen Typ T, der keine Bestellung enthält. Sie können es verwenden, um ein zu erstellen std::multimap<U, T>, aber Sie können es nicht verwenden, um ein zu erstellen std::map<U, std::set<T> >.
Björn Pollex