使用筛子找到小于 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 是一个longs 的数组来存储位。

您可以通过混合方法找到答案:

构建并运行筛子直至Integer.MAX_VALUE 将不超过Integer.MAX_VALUE 的素数收集到longs 的数组中 观察到你可以在达到候选号c 的平方根时停止检查除数 这意味着您已经拥有大于Integer.MAX_VALUE 值的所有潜在除数 使用除数数组过滤Integer.MAX_VALUEn之间的数字

由于您不需要在Integer.MAX_VALUE 之后存储额外的素数,因此您的代码不会耗尽内存。

【讨论】:

感谢您提到 BitSet 并没有充分降低内存需求。如果我认为这是正确的,它仍然需要多达 2^60 字节的内存。我不相信当前常见的桌面处理器可以解决那么多问题。

以上是关于使用筛子找到小于 LONG 数的素数的主要内容,如果未能解决你的问题,请参考以下文章

三 数论的编程实验

找出所有小于 200 万的素数之和需要多少时间?

找到素数最快的算法是啥?

大数的素数分解

使用 Erastothene 筛法找到 2 到 1000 的素数 [重复]

java Eratostenes的筛子(素数)