使用筛子找到小于 LONG 数的素数
Posted
技术标签:
【中文标题】使用筛子找到小于 LONG 数的素数【英文标题】:finding prime numbers less than a LONG number using sieve 【发布时间】:2016-08-11 14:29:06 【问题描述】:我必须找到小于或等于给定数字n
的素数数量。我正在使用埃拉托色尼筛法寻找素数。
这是我写的代码:
static int find_prime(int n)
boolean[] arr = new boolean[n+1];
Arrays.fill(arr, true);
for(int i=2;i<=n;i++)
if(arr[i]==true)
for(int j=2*i; j<=n; j+=i)
arr[j] = false;
int count=0;
for(int i=2;i<=n;i++)
//System.out.print(arr[i]+" ");
if (arr[i] == true)
count++;
return count;
此代码适用于 integer
值,但我必须为 long
数字实现它。并且 Java 不允许创建 long
大小的数组,所以 boolean[] arr = new boolean[n+1];
不起作用。
有人可以建议我解决这个问题的方法吗?
【问题讨论】:
Java array with more than 4gb elements的可能重复 您已经为您的筛子购买了 10 Exabytes 内存,对吧? 有更节省空间的方法来存储布尔序列。例如,一个位域。此外,您实际上不必在筛子中表示偶数。 @khelwood 这将把他带到 2^36 - 比 2^31 有了很大的改进,但仍然比他想要达到的 2^63 差很多。 您可能对segmented sieve 感兴趣。 【参考方案1】:您将没有足够的内存来表示整个筛子,因为它以艾字节为单位。即使BitSet
也无法满足您需要的所有索引,因为最终它uses 是一个long
s 的数组来存储位。
您可以通过混合方法找到答案:
构建并运行筛子直至Integer.MAX_VALUE
将不超过Integer.MAX_VALUE
的素数收集到long
s 的数组中
观察到你可以在达到候选号c
的平方根时停止检查除数
这意味着您已经拥有大于Integer.MAX_VALUE
值的所有潜在除数
使用除数数组过滤Integer.MAX_VALUE
和n
之间的数字
由于您不需要在Integer.MAX_VALUE
之后存储额外的素数,因此您的代码不会耗尽内存。
【讨论】:
感谢您提到 BitSet 并没有充分降低内存需求。如果我认为这是正确的,它仍然需要多达 2^60 字节的内存。我不相信当前常见的桌面处理器可以解决那么多问题。以上是关于使用筛子找到小于 LONG 数的素数的主要内容,如果未能解决你的问题,请参考以下文章