43

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

4

5 回答 5

68

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

于 2013-04-29T19:36:47.070 回答
26

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

地图可用于存储独特的事物,以及“价值”

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

向量对于存储序列有序(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.
于 2013-12-04T08:29:35.000 回答
6

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

于 2015-10-30T21:47:21.050 回答
4
  • vector在容器后面插入和删除更快。您可以通过运算符 [] 访问元素。
  • dequeue类似于,vector但它具有前端插入和删除功能。
  • set只有钥匙,而mappair。这两个容器在容器中间插入和删除都更快。您还可以使用 STL 算法通过查找来访问元素。
于 2013-04-29T20:31:47.600 回答
3

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

于 2013-04-29T19:35:23.980 回答