有效地存储稀疏填充的2D网格

时间:2014-04-18 21:21:02

标签: java c design-patterns

我有一张巨大的地图,上面有瓷砖。 它是一个地牢,所以显然有很多空的空间,我会在那里存储空值。

显然,拥有一个巨大的2D阵列是一种选择,但我认为它不是最优雅的。另外,当我想将它保存到文件时,存储大量的空标记并不是很整洁。

这样的东西,但是更大:

+--------------+
|   X     X    |
| XXX    XX    |
|   XXXXXXX    |
|    X   XX    |
|   XXX   XXX  |
|     X   X    |
+--------------+ 

我还有其他宽度×高度阵列的替代方案吗?

仅限Map<IntCoord, Tile>之类的内容?或者是否有类似场景的广泛使用的解决方案?

2 个答案:

答案 0 :(得分:4)

您可以使用三件事:

  1. 2D阵列。
  2. 列表。
  3. 地图。
  4. 2D阵列是最好的,除非您的地图很大,在这种情况下您可以使用列表。


    2D数组:

    优点:它具有最快的查找时间。

    缺点:它(很可能)占用的内存最多。

    查找时间可能大大超过内存成本。除非你的地牢是成千上万的瓷砖,否则这可能就是你要走的路。


    列表(可能是ArrayList):

    优点:仅存储您需要的物品。

    缺点:查找时间会很糟糕。

    虽然列表会占用更少的内存,但查找图块或项目需要更长的时间,因为您必须遍历列表以查找与位置匹配的内容。


    地图(可能是HashMap):

    优点:每个地点都会链接到每个地图的一个对象,因此查找时间就可以了。

    缺点:查找时间不是最佳的,会使用适量的内存。

    地图位于列表和数组之间。这将占用比数组更多的内存,但具有比列表更好的查找时间。


    由于查找时间的原因,2D阵列是最好的。在大多数现代计算机上,内存不是问题。如果是,您可以始终将当前未使用的区域缓存到文件中,并根据需要动态加载它们。

答案 1 :(得分:2)

我对在运行时如何将数据存储在内存中的评论很多,因为Anubian的答案似乎已经足够好了。我也同意他的看法,除非你有一些严格的内存限制和/或你的地牢确实很大(例如10,000 x 10,000),那么就没有真正的理由将它存储为一个2D数组。您节省的编码工作量和获得的运行时性能几乎肯定会超过您使用列表,地图等可能获得的空间效率优势。如果您确实没有足够的RAM存储地牢,您可以随时将它们分成块并在任何给定时间仅加载您需要的块(通常,无论播放器当前处于什么阻挡状态,加上可能还有几个相邻的块,以便当玩家从中移动时没有明显的加载时滞一个街区到下一个)。这比一个大数组要多得多,但仍然可能比将数据存储在一些稀疏数据结构中更容易,然后每次访问时都必须计算每个单元的内容。

但是,至于将其存储到文件中,您可能需要考虑Run Length Encoding (RLE)

为RLE编写编码和解码函数很简单,你可以随意决定你自己的语法和字符集等。

您尝试解决的问题(2D网格的高效编码)实际上非常类似于Conway的生命游戏模拟程序中存储状态的问题,以及最常见的文件之一他们使用的格式是RLE:http://conwaylife.com/wiki/Run_Length_Encoded

你的示例地牢类似于生命游戏对象/状态/你甚至可以使用他们使用的相同的精确RLE编码,在这种情况下你可以为你的示例地牢获得类似的东西:

# Optional comment lines
#   (perhaps a dungeon name and/or description?)
x = 14, y = 6
3bo5bo$b3o4b2o$3b7o$4bo3b2o$3b3o3b3o$5bo3bo!
相关问题