【问题标题】:C++ data structure to perform indexed list执行索引列表的 C++ 数据结构
【发布时间】:2014-10-10 03:09:52
【问题描述】:

我正在寻找最有效的数据结构来维护索引列表。您可以根据 STL 地图轻松查看它:

std::map<int,std::vector<int> > eff_ds;

我以这个为例,因为我目前正在使用这个设置。我想要执行的操作是:

  • 根据键插入值:类似于 eff_ds[key].push_back(..);
  • 根据每个键打印数据结构的内容。

我也在尝试使用无序映射和前向列表,

std::unordered_map<int,std::forward_list<int> > eff_ds;

如果我使用 C++ 或有其他选择,这是我能在时间上做的最好的吗?

更新

只要我对所有键都执行相同的操作,我就可以进行任何一种方式的插入 - 前/后。为了使我的问题更清楚,请考虑以下几点:

在我的算法的每次迭代中,我将有一个外部块给我一个(键,值)——它们都是单个整数——作为输出对。当然,我必须将此值插入到相应的键中。此外,在不同的迭代中,可能会返回具有不同值的相同键。最后我的输出数据(写入文件)应该是这样的:

k1: v1 v2 v3 v4
k2: v5 v6 v7
k3: v8
.
.
.
kn: vm 

这些迭代的数量相当大~1m。

【问题讨论】:

  • 这两个听起来都是不错的解决方案。为什么它们还不够?您是否有使它们无效的特殊要求?你的数据集足够大吗?您最关心的特定操作是什么(查找?删除?插入?)
  • 我只关心从后/前插入,没关系。我的数据集非常大,可能的键数可能超过 100 万个,但每个节点的项目数超过数百个。您可以将其视为一个大图,但连接稀疏。我有兴趣只添加边并根据每条边打印图形的内容。希望这可以说清楚。我只是想知道 C++ 是否有更聪明的方法。
  • 使用 unordered_map 将使单元素访问速度极快,但顺序访问速度极慢。如果您需要用一个键和映射中的所有键打印出所有关联的值,我会选择一个 std::map。否则,如果您只单独访问键,请使用 unordered_map。由于您已经在考虑键,所以我不会谈论邻接列表/向量。
  • @MarcoA。 “unordered_map ...顺序访问非常慢...我会选择std :: map”...是什么让您产生了这个想法?给定一个合理的哈希函数和默认的 max_load_factor 1,您可能会有 10-55% 的空桶 - 在内存中是连续的,并且只有指针大小非常适合缓存以跳过。与 vector 存储递增的键值相比,由于追逐指针,它的迭代(和索引)很慢,但 std::map 无论如何都有同样的弱点。
  • 您是否需要考虑添加到键中的重复值? IE。假设您的算法产生 (5, 7),然后这种组合再次发生,您希望键 5 具有 (7,7) 还是仅具有 (7)?\

标签: c++ data-structures map stl


【解决方案1】:

您的问题有两个方面:

  1. 在您希望能够使用数字键查找容器中的项目的情况下,最好使用什么容器,具有大量键,并且键是稀疏的

    数字键可能会为此提供一个向量,但是如果键是稀疏填充的,则会浪费大量内存。

    假设您不想按顺序遍历键(您没有将其声明为要求),那么 unordered_map 可能是最好的选择。

  2. 什么是数字列表的最佳容器,允许在任一端插入并能够按顺序检索数字列表(外部映射的值类型)

    这个问题的答案取决于您希望在前面插入元素的频率。如果这种情况经常发生,那么您可能需要考虑使用 forward_list。如果您主要在末尾插入,那么向量的开销会更低。

根据您更新的问题,由于您可以限制自己将值添加到列表的末尾,并且由于您不关心列表中的重复条目,我建议使用std::unordered_map&lt;int,vector&lt;int&gt; &gt;

【讨论】:

  • @Swami 已更新以考虑您的更新,尽管建议没有太大变化!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-01-06
  • 1970-01-01
  • 2014-09-10
  • 1970-01-01
  • 1970-01-01
  • 2012-02-18
  • 1970-01-01
相关资源
最近更新 更多