std :: multiset <int>与std :: map <int,std :: size_t =“”>用于保存多个可重复的整数值</int,> </int>

时间:2012-05-30 09:40:58

标签: c++ stl containers

我想创建一个记录来保存有关

的信息
  • a)存在什么样的元素和
  • b)存在的各种元素的数量

在树的节点中。我只会为叶子节点显式存储这些信息,而父节点的信息可以通过组合所有子节点的信息来获得(例如,子节点1有3个对象的A,1个对象的B,子节点2有1个A的对象,C对象的2个对象有4个A对象,1个B对象和2个C)。

从父节点请求此信息时,我会小心不要首先请求,使用和丢弃子节点的信息,然后是其父节点,但向上构造将是一个常见的操作。其他两个常见的操作直接来自我存储的内容:是X类的对象吗?有多少种X的对象?还有如何存在多种物体?

对象种类表示为整数,对象编号始终为整数值。什么是更好的选择(以及所选择的选择的参数):

  • 使用std::multiset<int>,并使用std::multiset::count()std::multiset::find()操作(更容易联合,但元素重复,难以获得完全不同的元素数)
  • 使用std::map<int, std::size_t>作为关键字和对象数作为值(没有重复元素,std::map::find()函数存在,size给出正确数量的对象种类存储,但访问非现有元素无意中增加了大小)

感谢您的建议!

2 个答案:

答案 0 :(得分:7)

要根据比较谓词存储 n 项目的 n 项目,<{1}}分配 n 二进制搜索树节点(*)。 std::multiset仅分配 k (略大)节点。

当比较谓词可以认为两个项目相等时,您可以使用std::map,但仍必须明确存储,因为它们在比较谓词不检查的某些方面有所不同。此外,迭代std::multiset生成每个 n 项,而multiset将生成每个 k 不同的项目,其中包含每个

如果项目只是整数,请使用map。您的“多少个不同的项目”查询将只是对std::map的调用,该调用会在固定的时间内运行。

您声称“访问不存在的元素会无意中增加大小”仅在您使用size访问节点时才会出现。 find不会出现此行为。

(*)C ++标准并不保证这些容器是作为(平衡的)BST实现的,但在我见过的所有实现中,它们都是。

答案 1 :(得分:2)

排序std::vector<int>怎么样?您需要的操作可以满足如下:

  • 是否存在X类对象? std::binary_search
  • 有多少种X对象? std::equal_range,从.first减去.second
  • 有多少种物品?
    • std::unique_copy后跟size()副本,或者......
    • 使用单独的计数器,在插入向量之前调用std::binary_search

与树状结构相比,此方法的优点是缓存局部性(所有数据都是连续的)和更低的内存占用。在不了解您的数据的情况下,我无法确定它是更快还是更慢。你必须对它进行分析以找出答案,但我有预感,这将比你预期的更好。

这里最大的权衡是表达能力。 std::map方法可能更好地逻辑地传达您正在做的事情,即对象ID和计数之间的关系。