【问题标题】:How to represent a small map of integers as an array?如何将一个小的整数映射表示为一个数组?
【发布时间】:2011-09-28 02:18:39
【问题描述】:

假设我要构建一个small简单的map,其中key是N个整数(固定,通常是1),value是M个整数(也是固定的,通常是1)。

现在我想将数据存储为一个整数数组,以提高空间效率。我在 JVM 中编程,但它不应该真正产生影响,除非算法需要将 指针 存储为整数。

有没有人定义了一个可以做到这一点的简单数据结构?

[编辑] 到目前为止,我的答案似乎表明没有人理解我的问题,所以我会尽力澄清。首先,忘记M和N;想象一下,我说的是一个 int 键和一个 int 值。 AFAIK,如果你想使用一个普通的 HashMap,其中键是整数,值是整数,那么你最终会得到至少 2 + 3 * N 个对象,其中 N 是条目数。

我想知道的是,您能否将所有这些整数打包在一个原始整数数组中,从而将对象数减少到两个,而与键的数量无关。一个用于 int[],另一个用于为您提供一些类似地图的接口的包装器对象。我的键和值都不会为空。而且我也不需要完整的标准 java.util.Map 实现。我只需要、获取、放置和删除,获取和返回 primitive ints 而不是 Integer 对象。访问确实不需要需要 O(1),就像在普通的 HashMap 中一样。

【问题讨论】:

  • 您认为这将如何完成?此外,如果您加强空间要求,其他一些属性(如时间或大小)也需要放松。
  • 如果我知道它是怎么回事,我就不会要求它了。但仅仅因为我不知道它是怎么回事并不意味着它是不可能的。我知道这些妥协。我说的是可能有数百万张小地图。
  • 在这种情况下,我不明白你的问题描述。
  • 我认为没有人这样做。修改后是否更清晰?
  • 不多。显示一些代码来演示您现在所做的事情。

标签: java arrays data-structures map integer


【解决方案1】:

由于 ArrayList(实际上是 AbstractList) 类已经适当地重写了 equals 方法,因此您可以像这样直接使用映射:

Map<List, List> map = new HashMap<List, List>();

【讨论】:

  • 我想节省空间,因此我想使用普通的 HashMap,它为每个键创建至少一个对象,尤其是不是整数对象的 ArrayList,而不是原始整数数组!恐怕你完全错过了我的意思。可能我没有表达清楚。
【解决方案2】:

据我所知,答案是否定的,至少在 Java 中不是。

但是您可以简单地将键和值保存在具有匹配索引的 int 数组(每个)中,如果您保持键数组排序,则可以执行二进制搜索。

不过,Java 数组的问题在于它们是固定大小的结构,因此如果您想要存储的元素多于分配给数组的元素,那么重新分配它们的成本非常高。

所以你必须在数组的大小和重新分配的数量之间进行权衡,这可能类似于ArrayList 的做法。

另一个稍微小一点的问题是 int 是一个原始类型,没有 null 值,但你可以指定一个特殊的 int 值来表示 null。

【讨论】:

  • 这与上一个答案类似,只是对键进行了排序。所以我放慢了速度,但速度更快了。真的我应该尝试两者,因为我还不知道我的 put/get 比率。
  • 其实我错了。每次操作都会更快,因为你不能只在最后插入,你必须遍历所有键才能知道它是否已经存在。
  • 是的,在插入时您执行相同的二分查找,如果键不存在,则使用System.arrayCopy 将其之外的所有条目向右移动。另一个重要的区别是两个一维数组比一个二维数组更有效。
  • 在 put 上还是很慢吧?考虑到它的插入排序?
  • @kyun 好吧,如果你正在优化空间,你总是不得不放弃一些速度。当然这取决于实际的使用模式,但通常在地图插入速度方面不如查找。
【解决方案3】:

我想我理解了这个问题,我会尝试解决方案:

实现您想要的非常简单的方法是保留一个二维数组int array[NKeys][2],其中array[i][0] 是键,array[i][1] 是 M 值之一。您可以,然后迭代数组,对于key 的每个查询,返回所有array[i][1],这样array[i][0] == key。当然,这适用于单个 int 键而不是一组 int 键。此外,这在复杂性方面非常糟糕。如果不添加更多 Java 对象/C 指针,我想不出任何其他方法。

【讨论】:

  • 我喜欢这个。根本不做任何散列,并遍历键。似乎是迄今为止最好的解决方案。为什么我自己没有想到呢?
  • 可能是因为它非常复杂:)。但正如您已经说过的,这是您为不使用更多对象而做出的妥协。
猜你喜欢
  • 2018-03-25
  • 2018-11-06
  • 1970-01-01
  • 2019-09-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-19
  • 2015-07-14
相关资源
最近更新 更多