有没有在C ++链接哈希集合?(Is there a linked hash set in C++?

2019-08-19 08:00发布

Java有一个LinkedHashSet ,这是一套具有可预知的迭代顺序。 什么是C ++最近的可用数据结构?

目前我正在同时使用一组和载体复制我的数据。 我插入我的数据进入设置。 如果成功地插入的数据(表示数据不是已存在于所述组),那么我的push_back到载体中。 当我通过数据迭代,我用的是载体。

Answer 1:

如果你可以使用它,那么Boost.MultiIndex还与sequencedhashed_unique指标是相同的数据结构LinkedHashSet

如果做不到这一点,保持一个unordered_set (或hash_set ,如果这是你实现提供的)某种类型与它的列表节点,并使用该列表节点自己处理的顺序。

与你目前在做什么的问题( setvector )是:

  • 该数据的两个副本(当数据类型是大的可能是一个问题,这意味着你的两个不同的迭代返回引用不同的对象 ,尽管有相同的价值观。这将是一个问题,如果有人写一些代码,比较在两种不同的方式获得的“相同”的元素的地址,期待地址相等,或者如果你的对象有mutable由顺序比较忽略数据成员,有人写道,希望通过查找变异,并查看更改代码在序列迭代时)。
  • 不像LinkedHashSet ,没有在序列中删除元素快速的方式。 如果你想通过值而不是位置删除,那么你要搜索的值删除向量。
  • set具有从哈希集合不同的性能特征。

如果你不关心,这些事情,那么你有什么可能是罚款。 如果重复是唯一的问题,那么你可以考虑保持指针的矢量集合中的元素,而不是复制的载体。



Answer 2:

从Java在C ++中复制LinkedHashSet,我想你会需要两个香草std::map (请注意,您将得到LinkedTreeSet而不是真正的LinkedHashSet,而不是将得到O(log n)的插入和删除)这个工作。

  • 一个使用实际值作为密钥和插入顺序(通常是int或长整型)的值。
  • 另一者是反向,使用插入顺序键和实际值的值。

当你要插入,您使用std::map::find第一std::map ,以确保在它里面不存在相同的对象。

  • 如果已经存在,忽略了新的。
  • 如果没有,你映射递增插入为了既能此对象std::map我前面提到的。

当你要通过插入的顺序通过这个迭代,你通过第二循环std::map ,因为它会通过(即落入任何插入顺序排序std::mapstd::set将被自动排序) 。

当你要从中删除一个元素,您使用std::map::find让插入的顺序。 使用插入此为了去除从第二元件std::map ,并从第一个删除该对象。

请注意,这个方案并不完美, 如果你打算使用这种长期的基础上 ,你将需要“紧凑型”一定数量清除后的插入顺序,因为你将最终耗尽插入顺序(2 ^为unsigned int的32个索引或2 ^ 64索引无符号长长整型)。 为了做到这一点,你需要把所有的“值”的对象为载体,明确从两个地图的所有值,然后重新插入值从向量回这两个地图。 这个过程需要O(nlogn)时间。

如果您使用C ++ 11,可以更换第一std::mapstd::unordered_map来提高效率,你将无法与它虽然更换第二个。 其原因是, std::unordered map使用索引的哈希码,使得指数不能可靠地在这种情况下进行排序。



Answer 3:

你可能想知道的std ::地图不给你任何的(log n)的为“零”查找时间。 而使用std :: tr1 ::无序是有风险的业务,因为它破坏任何顺序获得恒定的查找时间。

尝试来砸升压多指数容器更自由地它是。



Answer 4:

你描述你的组合方式std::setstd::vector听起来像是你应该做的事情,除非使用std::unordered_set (相当于Java的HashSet的)和std::list (双向链表)。 你也可以使用std::unordered_map与一个迭代器列表在哪里可以找到您存储(如果该键是从对象(或只是其中的一部分)不同)的实际对象一起存储键(查找)。

Boost库确实提供了一些这些类型的容器和查询指标的组合的。 例如, 该双向列表快速查找窗口例子 。



文章来源: Is there a linked hash set in C++?
标签: c++ set