我试图在600851475143之前获得所有素数。 我正在使用Eratosthenes的Sieve。 这需要我创建一个巨大的布尔数组。 不好的想法,你可能会耗尽内存。 任何其他方式。我尝试使用一个字符串,使用每个索引值为0& 1表示真或假。但indexOf方法也返回int。
接下来我使用2d数组来解决我的问题。 还有其他更好的存储方式吗?
答案 0 :(得分:7)
600851475143布尔值的内存要求最多为70Gb。这是不可行的。您需要按照Stephan的建议使用压缩,或者找到用于计算素数的不同算法。
答案 1 :(得分:6)
我有一个类似的问题,我使用了一个位设置(基本上按顺序设置1或0表示所需的偏移量),我建议使用EWAHCompressedBitmap它也会压缩你的位集
编辑
正如Alan所说,BitSet会占用70GB内存,但你可以做另外一件事:拥有多个BitSets(连续的BitSets以便你可以计算绝对位置)并在内存中加载你需要的BitSet就像延迟加载一样,在这种情况下,您将控制所使用的内存。
答案 2 :(得分:2)
对于每个数字而言,如果它是一个素数或者不是如此大的数量,那么记住它是不切实际的(一般来说筛子对于大数字来说是一种非常缓慢的方法)。
从这个link你可以知道有多少素数可以预期小于X.对于你的6000亿范围,你可以预期在这个范围内存在大约200亿个素数。将它们存储为long []将需要大约160GB的内存...这显着超过建议的70GB用于存储每个数字的单个位,如果排除偶数,则为一半(2是唯一的偶数素数)。
对于台式电脑,35GB的内存可能有点多,但一个好的工作站可以拥有那么多的RAM。我会尝试使用位移/屏蔽的二维数组。
我仍然希望你的筛选代码运行相当多的时间(从几天到几年)。我建议你研究比筛子更先进的初级检测方法。
答案 3 :(得分:2)
您可以使用HotSpot的内部sun.misc.Unsafe API来分配更大的数组。 I wrote a blogpost how to simulate an array with it但是,它不是官方Java API,因此它有资格成为黑客。
答案 4 :(得分:0)
使用BitSet。然后,您可以设置任何索引元素。 600851475143是2^39
因此在内部仅占用39位(实际上它将占用64位,因为它使用长)。
你可以实际上移动到2^63
,这对于大多数目的而言是巨大的