【问题标题】:How to create array of size greater than integer max [duplicate]如何创建大小大于整数最大值的数组[重复]
【发布时间】:2013-04-15 12:09:08
【问题描述】:

我试图获得 600851475143 之前的所有素数。 我为此使用了埃拉托色尼筛。 这需要我创建一个如此巨大的布尔数组。 坏主意,你可能会耗尽内存。 任何其他方式。我尝试使用字符串,使用值为 0 和 1 的每个索引来表示真或假。但 indexOf 方法也返回 int。

接下来我使用二维数组来解决我的问题。 还有其他更好的方法来存储如此庞大的数组吗?

【问题讨论】:

  • "我试图获取 600851475143 之前的所有素数。"对于欧拉计划问题,这完全是错误的方法。
  • 我建议,如果您的解决方案要求您创建 6000 亿个数组条目,那么您需要采用新方法。
  • @Ashok Vector 由一个数组支持,我不知道这会有什么不同。
  • @Ashok 矢量由数组支持并同步。帮不上忙。
  • +1 : 不能使用向量。

标签: java algorithm data-structures


【解决方案1】:

600851475143 布尔值的内存要求最多为 70Gb。这是不可行的。您需要按照 Stephan 的建议使用压缩,或者找到一种不同的算法来计算素数。

【讨论】:

  • 可行,但可能不太现实!
  • 好吧,我可能应该澄清一下,虽然可能,但如果不是一台非常高端的计算机(或可能是超级计算机),它是不可行的(又名实用的)。
  • 我不想使用库,所以即使 EWAHCompressedBitmap 很有前途,我也会使用每个大小为 32 mb 的 BitSet。并为其添加延迟加载。寻找更好的选择。这个问题的传统方法太慢了,但是可以。
【解决方案2】:

我遇到了类似的问题,我使用了一个位集(基本上按顺序将 1 或 0 设置为所需的偏移量),我建议使用 EWAHCompressedBitmap 它也会压缩您的位集

编辑

正如 Alan 所说,BitSet 将占用 70GB 内存,但您可以做另一件事:拥有多个 BitSet(连续的,以便您可以计算绝对位置)并在内存中加载您当时需要的 BitSet就像延迟加载一样,在这种情况下,您将可以控制所使用的内存。

【讨论】:

    【解决方案3】:

    对于如此大的数量来说,记住每个数字是否是素数是不切实际的(对于大数字来说,筛子通常是一种非常慢的方法)。

    从这个link 中,您可以了解预计有多少个质数小于 X。对于您的 6000 亿范围,您可以预计在该范围内大约存在 200 亿个质数。将它们存储为 long[] 将需要大约 160GB 的内存......这明显超过了建议的 70GB 用于存储每个数字的单个位,如果排除偶数(2 是唯一的偶数),则为一半。

    对于一台台式电脑来说,35GB 的内存可能有点多,但一个好的工作站可以有这么多的 RAM。我会尝试使用位移/屏蔽的二维数组。

    我仍然希望您的筛选代码能够运行 相当长的 时间(从几天到几年不等)。我建议你研究比筛法更先进的素数检测方法。

    【讨论】:

      【解决方案4】:

      您可以使用 HotSpot 的内部 sun.misc.Unsafe API 来分配更大的数组。 I wrote a blogpost how to simulate an array with it 但是,它不是官方的 Java API,所以它有资格作为 hack。

      【讨论】:

        【解决方案5】:

        使用BitSet。然后您可以设置位任何索引元素。 600851475143 是2^39,因此在内部只占用 39 位(实际上它会占用 64 位,因为它使用 long)。

        您实际上可以移动到2^63,这对于大多数用途来说都是巨大的

        【讨论】:

        • 他需要 2^39 位,而不是 39。
        • OP 需要 600851475143 位标志(如果跳过偶数,则需要一半,如果还跳过 3 的倍数,则需要三分之一,如果跳过更多小素数的倍数,则少一些)。这仍然会比在BitSet 中索引的条目更多。
        • @assylias 是的,你的权利
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-06-12
        • 1970-01-01
        • 2011-12-17
        • 1970-01-01
        • 1970-01-01
        • 2020-05-10
        • 2016-07-31
        相关资源
        最近更新 更多