我需要一个像地图一样的数据结构,但每个键可能有多个与之相关的值,但我需要将与单个键对应的所有值作为对象数组。那么哪种数据结构最适合这样做。我不需要在数据结构中搜索,我只需要快速访问与特定键对应的所有值。我查看了std :: multimap但它没有返回特定键的所有值。那么我可以使用C ++中最好的数据结构呢?
答案 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));
您可能应该对程序进行基准测试,以确定哪个容器更方便。