C++ std::set 与向量或映射的优点

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16286714/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 20:13:16  来源:igfitidea点击:

advantages of std::set vs vectors or maps

c++stdvectorstdmapstdset

提问by brunodd

This may be a stupid question, I am quite new to C++ and programming in general. I wish to understand the use of several STL containers and with that in mind, I was wondering what the advantages are of using std::set vs for example using vectors or maps? I can't seem to find an explicit answer to this question. I noticed that sets use maps, but then why not always use maps or always use sets. Instead 2 quite similar containers are provided. Thanks in advance.

这可能是一个愚蠢的问题,我对 C++ 和一般编程很陌生。我想了解几个 STL 容器的使用,考虑到这一点,我想知道使用 std::set 与例如使用向量或映射的优点是什么?我似乎无法找到这个问题的明确答案。我注意到集合使用地图,但为什么不总是使用地图或总是使用集合。而是提供了 2 个非常相似的容器。提前致谢。

回答by David Rodríguez - dribeas

Both std::setand std::mapare associative containers. The difference is that std::sets contain only the key, while in std::mapthere is an associated value. Choosing one over the other depends mainly on what the task at hand is. If you want to build a dictionary of all the words that appear in a text, you could use a std::set<std::string>, but if you also want to count how many times each word appeared (i.e. associate a value to the key) then you would need an std::map<std::string,int>. If you don't need to associate that count, it does not make sense to have the intthat is unnecessary.

这两个std::setstd::map是相关联的容器。区别在于std::sets 只包含键,而 instd::map有一个关联的值。选择一个主要取决于手头的任务是什么。如果您想为文本中出现的所有单词构建一个字典,您可以使用 a std::set<std::string>,但如果您还想计算每个单词出现的次数(即,将一个值与键关联),那么您需要一个std::map<std::string,int>. 如果您不需要关联该计数,那么拥有该计数是没有意义的int

回答by Angel Koh

a set is useful for storing unique things like an enum for "typeOfFruits"

集合对于存储独特的东西很有用,比如“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"; }

a map is useful for storing unique things, plus a 'value'

地图对于存储独特的东西很有用,再加上一个“价值”

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

a vector is useful for storing things where the sequence is ordered (push_back()). imagine you are scanning your fruits in a checkout, and the program tracks this scanning.

向量可用于存储序列已排序的内容(push_back())。假设您正在结帐时扫描水果,并且程序会跟踪此扫描。

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.

回答by user2554481

No body has mentioned the facts that std::setis actually immutable. You should not change the value of any element in it. std::setdoes not track over changes so when you edit a element in it you go behind its back and are likely to change its inner ordering. This is a risky behavior. Therefore use std::mapif you want to edit elements after you put them into the container. Make sure you use keyto induce ordering and everything you need to change afterwards into value.

没有任何机构提到过std::set实际上不可改变的事实。您不应更改其中任何元素的值。std::set不会跟踪更改,因此当您编辑其中的元素时,您会落后于它,并且可能会更改其内部顺序。这是一种危险的行为。因此,std::map如果您想在将元素放入容器后对其进行编辑,请使用。确保您使用key来诱导排序以及之后需要更改的所有内容value

回答by lucas92

  • vectoris faster for insertions and deletions at the back of the container. You can access the elements via the operator [].
  • dequeueis similar to vectorbut it features front insertion and deletion.
  • setonly has the key while maphas a pair. Both of these containers are faster for insertion and deletion in the middle of the container. You can also access elements via find with the STL algorithms.
  • vector在容器后面插入和删除的速度更快。您可以通过运算符 [] 访问元素。
  • dequeue类似于vector但它具有前端插入和删除功能。
  • set只有钥匙而mappair. 这两个容器在容器中间插入和删除都更快。您还可以使用 STL 算法通过 find 访问元素。

回答by Scott Jones

It comes down to the complexity guarantees that are most desired for your application, with respect to insertion, removal, retrieval, etc. I highly recommend Scott Meyers' Effective STL.

它归结为您的应用程序最需要的复杂性保证,涉及插入、删除、检索等。我强烈推荐Scott Meyers 的 Effective STL