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

std::unordered_map containing another std::unordered_map?

本文关键字:map std uncodered 另一个 包含 unordered      更新时间:2023-10-16

我们正在用c++为学校做一个游戏项目。我负责地图对象,它将包含炸弹、玩家、墙和盒子等实体。我的地图上有3个集装箱:

  • 玩家的std::列表(多个玩家可以站在同一个箱子上(
  • 墙的std::unordered_map<int, std::unordered_map<int, AEntity*> >
  • 另一个std::unordered_map<int, std::unordered_map<int, AEntity*> >用于炸弹+盒子

目的是在地图上非常快速地访问一个实体,实体的数量可能非常多。

这就是为什么我想到了无序地图,我计划以这种方式使用它们:

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:

首先,对于这种使用来说,无序映射的速度那么快吗?我对无序地图很陌生。

问题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;
}

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

对于std::unordered_map

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

对于std::map

  • 为映射中的每个元素动态分配新内存,如果要向映射中添加数百万个元素,这可能会很慢
  • 删除元素也是一项logn操作,如果您经常这样做,操作可能会很慢
  • 因为它是一棵树,所以它是排序的,所以可以按顺序遍历元素,这在无序映射中是不可能的

还有很多其他的问题,我建议查一下,在stackoverflow上已经有很多这种类型的问题重复了。

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

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

恢复到阵列将始终以一些额外RAM为代价,提供更快的实体访问和插入。我不知道可能的坐标范围,但假设你的地图范围是(0,0(-(10241024(。为此使用指针数组将只使用1024 x 1024 x 8字节=8MBytes的RAM,无论您在其中存储多少实体。我必须运行一些测试来确保这一点,但我认为,如果映射中80%以上都是实体,那么数组方法实际上会比unordered_map方法使用更少的RAM。

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

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

相关文章: