it-swarm.com.de

Vorteile von std :: set gegenüber Vektoren oder Karten

Dies mag eine blöde Frage sein, ich bin ziemlich neu in C++ und der Programmierung im Allgemeinen. Ich möchte die Verwendung mehrerer STL-Container verstehen und habe mich vor diesem Hintergrund gefragt, welche Vorteile die Verwendung von std :: set gegenüber der Verwendung von Vektoren oder Karten bietet. Ich kann scheinbar keine explizite Antwort auf diese Frage finden. Mir ist aufgefallen, dass Sets Maps verwenden, aber warum nicht immer Maps oder Sets verwenden. Stattdessen sind 2 recht ähnliche Behälter vorgesehen. Danke im Voraus.

39
brunodd

Beide std::set und std::map sind assoziative Container. Der Unterschied ist, dass std::sets enthalten nur den Schlüssel, während in std::map es gibt einen zugehörigen Wert. Die Wahl der richtigen Reihenfolge hängt hauptsächlich von der jeweiligen Aufgabe ab. Wenn Sie ein Wörterbuch aller in einem Text vorkommenden Wörter erstellen möchten, können Sie ein std::set<std::string>, aber wenn Sie auch zählen möchten, wie oft jedes Wort vorkommt (d. h. dem Schlüssel einen Wert zuordnen), benötigen Sie ein std::map<std::string,int>. Wenn Sie diese Anzahl nicht zuordnen müssen, ist es nicht sinnvoll, das nicht erforderliche int zu haben.

ein Set ist nützlich, um einzigartige Dinge wie eine Aufzählung für "typeOfFruits" zu speichern.

std::set<typeOfFruits> fruits;   
fruits.insert (banana);
fruits.insert (Apple);
fruits.insert (pineapple);

//it's fast to know if my store sells a type of fruit.
if (fruits.find (pear) == fruits.end())
{ std::cout<<"i don't have pear"; }

eine Karte ist nützlich, um einzigartige Dinge zu speichern, sowie einen 'Wert'.

std::map<typeOfFruits, double /*unit price*/> fruits;  
fruits[banana] = 1.05;
fruits[Apple] = 0.85;
fruits[pineapple] = 3.05;
//repeating pineapple will replace the old price (value)
fruits[pineapple] = 3.35;

//it's fast to know how much a fruit costs.
std::map<typeOfFruits, double /*unit price*/> itr = fruits.find(pineapple);
if (itr != fruits.end())
{ std::cout<<"pineapples costs: $" <<itr->second; }

ein Vektor ist nützlich, um Dinge zu speichern, bei denen die Sequenz geordnet ist (Push_back ()). Stellen Sie sich vor, Sie scannen Ihre Früchte an der Kasse, und das Programm verfolgt diesen Scanvorgang.

std::vector<typeOfFruits> fruits;
fruits.Push_back(Apple);
fruits.Push_back(Apple); 
fruits.Push_back(Apple);
fruits.Push_back(banana);
fruits.Push_back(banana);
fruits.Push_back(pineapple);
//i scanned 3 apples, 2 bananas and 1 pineapple.
24
Angel Koh
  • vector ist schneller für Einfügungen und Löschungen an der Rückseite des Containers. Sie können über den Operator [] auf die Elemente zugreifen.
  • dequeue ähnelt vector, verfügt jedoch über das Einfügen und Löschen von vorne.
  • set hat nur den Schlüssel, während map einen pair hat. Beide Container können schneller in der Mitte des Containers eingefügt und daraus gelöscht werden. Sie können mit den STL-Algorithmen auch über find auf Elemente zugreifen.
4
lucas92

Keiner hat die Tatsachen erwähnt, die std::set ist eigentlich unveränderlich. Sie sollten den Wert eines Elements darin nicht ändern. std::set verfolgt keine Änderungen. Wenn Sie also ein Element darin bearbeiten, werden Sie hinter seinem Rücken zurückbleiben und wahrscheinlich seine innere Reihenfolge ändern. Dies ist ein riskantes Verhalten. Verwenden Sie daher std::map, wenn Sie Elemente bearbeiten möchten, nachdem Sie sie in den Container gestellt haben. Stellen Sie sicher, dass Sie key verwenden, um die Bestellung zu veranlassen und alles, was Sie danach in value ändern müssen.

3
user2554481

Es kommt auf die Komplexitätsgarantien an, die für Ihre Anwendung in Bezug auf das Einsetzen, Entfernen, Abrufen usw. am meisten erwünscht sind. Ich empfehle dringend Scott Meyers 'Effective STL.

2
Scott Jones