std :: unordered_map包含另一个std :: unordered_map?

时间:2013-05-16 11:45:49

标签: c++ map stl hashtable unordered-map

我们正在用c ++开发一个学校游戏项目。 我负责地图对象,他将包含炸弹,玩家,墙壁和盒子等实体。 我的地图中有3个容器:

  • 玩家的std ::列表(多个玩家可以站在同一个案例中)。
  • 墙上有std::unordered_map<int, std::unordered_map<int, AEntity*> >
  • 其他std::unordered_map<int, std::unordered_map<int, AEntity*> >炸弹+盒子。

目标是在地图上非常快速地访问实体,实体数量可能非常高。

这就是我考虑unordered_maps的原因,我打算用这种方式使用它们:

Unordered_map A contain:
  KEY: y coord of the Entity || VALUE: pointer to unordered_map B

Unordered_map B contain:
  KEY: x coord of the entity || VALUE: pointer to the AEntity instance

问题1:

首先,unordered_maps是否适用于此类用途?我是unordered_maps的新手。

问题2:

其次,这是添加元素的可行方法吗?

int main(int ac, char **av)
{
   std::unordered_map <int, unordered_map <int, char*>> umap;

   (umap[4])[2] = "salut";
   std::cout << (umap[4])[2] << std::endl;
}

3 个答案:

答案 0 :(得分:4)

std::unordered_map是根据哈希表实现的,与根据树实现的std::map不同。这意味着对于unordered_map,访问通常为O(1),其中std::map为O(log n)。这些之间有很多不同之处,如果您不知道差异,我建议您查看数据结构书,但这里有一些:

std::unordered_map

  • 分配一个连续的内存数组,您可以使用reserve()来防止在不合时宜的时刻调整大小,但是由于哈希表的性质,这将总是分配比您实际使用时更多的空间
  • 计算哈希值很快,但在std::map
  • 中查找几个指针可能会更快

std::map

  • 为地图中的每个元素动态分配新内存,如果要向地图添加数百万个元素,这可能会很慢。
  • 删除元素也是一项日志操作,如果您经常这样做,可能会很慢。
  • 因为它是一棵树,所以它是有序的,所以你可以按顺序遍历元素,这是无序地图无法实现的。

还有很多其他的,我建议查找它们,stackoverflow上有很多这类问题的重复。

至于你的秒问题,这是添加和访问unordered_map中元素的有效方法。但是,如果您知道要放置在地图中的项目数量,我强烈建议您使用reserve()

答案 1 :(得分:2)

其他人已经解释过unordered_mapmap,但如果它真的是速度,那么我建议使用普通数组(或向量)。你说实体的数量可以“非常大”,据此我理解你正在处理密集数据(即大多数坐标都包含一个实体)。 unordered_map是一种散列映射,这意味着密集数据将快速填满桶。大型存储桶会降低速度并增加内存使用量,从而降低使用unordered_map的优势。

恢复数组将始终提供更快的访问和实体插入,但需要额外的RAM。我不知道可能的坐标范围,但是我们说你的地图范围是(0,0) - (1024,1024)。使用指针数组只能使用1024 x 1024 x 8字节= 8 MB的RAM,无论你存储多少实体。我必须运行一些测试来确保,但我认为如果你的地图超过80%填充了实体,那么阵列方法实际上会使用比unordered_map方法更少的RAM。

总而言之,我还想提一下,你不应该总是专注于速度。优化的C ++代码通常已经非常快,除非你真的,真的,真的需要我建议使用最简单的解决方案而不是最快的解决方案。

答案 2 :(得分:0)

当您需要访问其密钥时,unordered_map容器比map容器更快,但在尝试访问其元素子集时被认为效率较低。我认为,如果您直接访问unordered_map容器中包含的指针,那么效率会降低。 http://www.cplusplus.com/reference/unordered_map/unordered_map/