web-dev-qa-db-fra.com

avantages de std :: set vs vecteurs ou cartes

Cela peut être une question stupide, je suis assez nouveau pour C++ et la programmation en général. Je souhaite comprendre l'utilisation de plusieurs conteneurs STL et avec cela à l'esprit, je me demandais quels sont les avantages d'utiliser std :: set vs par exemple en utilisant des vecteurs ou des cartes? Je n'arrive pas à trouver une réponse explicite à cette question. J'ai remarqué que les ensembles utilisent des cartes, mais alors pourquoi ne pas toujours utiliser des cartes ou toujours des ensembles. Au lieu de cela, 2 conteneurs assez similaires sont fournis. Merci d'avance.

39
brunodd

Tous les deux std::set et std::map sont des conteneurs associatifs. La différence est que std::sets ne contiennent que la clé, tandis que dans std::map il y a une valeur associée. Choisir l'un plutôt que l'autre dépend principalement de la tâche à accomplir. Si vous souhaitez créer un dictionnaire de tous les mots qui apparaissent dans un texte, vous pouvez utiliser un std::set<std::string>, mais si vous voulez également compter le nombre de fois que chaque mot est apparu (c'est-à-dire associer une valeur à la clé), vous aurez besoin d'un std::map<std::string,int>. Si vous n'avez pas besoin d'associer ce nombre, il n'est pas logique d'avoir le int qui n'est pas nécessaire.

un ensemble est utile pour stocker des choses uniques comme une énumération pour "typeOfFruits"

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"; }

une carte est utile pour stocker des choses uniques, plus une "valeur"

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; }

un vecteur est utile pour stocker des choses où la séquence est ordonnée (Push_back ()). imaginez que vous numérisez vos fruits lors d'un paiement, et le programme suit cette numérisation.

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 est plus rapide pour les insertions et les suppressions à l'arrière du conteneur. Vous pouvez accéder aux éléments via l'opérateur [].
  • dequeue est similaire à vector mais il comporte une insertion et une suppression avant.
  • set n'a que la clé tandis que map a un pair. Ces deux conteneurs sont plus rapides pour l'insertion et la suppression au milieu du conteneur. Vous pouvez également accéder aux éléments via find avec les algorithmes STL.
4
lucas92

Aucun organisme n'a mentionné les faits qui std::set est en fait immuable. Vous ne devez pas modifier la valeur d'un élément qu'il contient. std::set ne suit pas les changements, donc lorsque vous éditez un élément, vous passez derrière son dos et vous risquez de changer son ordre interne. Il s'agit d'un comportement risqué. Utilisez donc std::map si vous souhaitez modifier des éléments après les avoir placés dans le conteneur. Assurez-vous d'utiliser key pour induire la commande et tout ce dont vous avez besoin pour changer ensuite en value.

3
user2554481

Cela se résume aux garanties de complexité les plus souhaitées pour votre application, en ce qui concerne l'insertion, le retrait, la récupération, etc. Je recommande fortement Scott Meyers 'Effective STL.

2
Scott Jones