我应该使用哪种数据结构?

时间:2013-06-07 06:06:05

标签: c++ data-structures c++11 map multimap

我需要一个像地图一样的数据结构,但每个键可能有多个与之相关的值,但我需要将与单个键对应的所有值作为对象数组。那么哪种数据结构最适合这样做。我不需要在数据结构中搜索,我只需要快速访问与特定键对应的所有值。我查看了std :: multimap但它没有返回特定键的所有值。那么我可以使用C ++中最好的数据结构呢?

2 个答案:

答案 0 :(得分:6)

  

我需要一个像地图一样的数据结构但是......

std::map<key, std::vector<value>>

8000万分是一个很好的打击 - 值得考虑其他选择。值得一点思考/实验/基准测试包括:

  • 稀疏直接索引......要实现这一点,你需要的内存不仅仅是8000万个数据点,而是它们所跨越的整个x / y / z空间,但是可以做{{1查找以查找单元格id的向量 - 这显然会很大 - 无论是可行的还是可取的,都不能从您的问题描述中看出来

  • 一个有序的向量...取决于数据结构元素插入和查找的顺序/重叠,以及您是否可以负担[x][y][z]std::map压缩步骤 - 您可以排序由于std::vector的连续内存使用

  • std::vector(x,y,z)值的binary_search优于std::map
  • vector ...假设说1亿桶容量应该加快插入速度。这可能比其他选项更慢或更快...索引的内存页面可能少于稀疏索引,但是连续内存上的std::unordered_map<key, std::vector<value>>以上,每次查找访问的内存页数最少,但是普通的散列技术,即使x,y,z坐标只有一点差异,你也会有效地随机(但可重复)散列桶,所以缓存命中可能比上面的所有其他选项更差。

实际基准测试始终是调整的最佳方式,最好使用配置文件确认成本是出于预期的原因。

答案 1 :(得分:4)

@TonyD的回答当然没问题,但与

相比有一些权衡
std::multimap<key, value> 

搜索给定密钥的所有值应该会给您相同的O(log N)复杂度

auto result = my_multimap.equal_range(my_key);

迭代仍然是O(N)复杂度:

for (auto it = result.first; it != result.second; ++it)
     // bla

然而,在所有真实世界std::multimap实现中,上面的迭代是基于节点的指针追逐“连续”值元素而不是你获得的连续迭代std::vector基于std::map。由于缓存局部性的原因,这可能很重要。

我可以从std::vector解决方案中看到的主要缺点是,您提交将所有值保持在一起可能会产生一些开销,具体取决于您复制数据的频率周围。

multimap方法可以更容易地从容器中插入/提取单个值

my_multimap.insert(std::make_pair(some_key, another_value);

auto it = my_map.find(some_key);
if (it != my_map.end()) 
    it->second.push_back(another_value);
else
    my_map.insert(std::make_pair(some_key, another_value));

您可能应该对程序进行基准测试,以确定哪个容器更方便。