在Java中提高埃拉托色尼筛法代码的效率

3

我在Java中编写了埃拉托色尼筛法的代码,但是我遇到了一些时间和空间效率问题。以下是代码:

import java.util.*;

class EratosthenesSeive
{

    public static void main(String args[])
    {

        ArrayList<Long> myPrimeList = new ArrayList<Long>();
        ArrayList<Long> myTempPrimeList = new ArrayList<Long>();
        ArrayList<Boolean> isPrimeNumber = new ArrayList<Boolean>();
        int index = 0;

        long ul = 1500l;
        long ll = 2;

        do
        {
            myTempPrimeList.add(ll);
            isPrimeNumber.add(true);
            ll++;
        }while( ll != (ul+1));

        for(long i : myTempPrimeList)
        {
            if(isPrimeNumber.get(index))
            {
                myPrimeList.add(i);
                for(long j = i ; j*i <= ul; j++)
                {
                    isPrimeNumber.set(myTempPrimeList.indexOf(j*i),false);
                }
            }
            index++;
        }

        System.out.println(myPrimeList);
    }
}

输入最多为10^3时,它似乎工作良好,在10^4时它只是卡住了,在10^5及以上,我会得到 OutOfMemoryError。 代码似乎工作得很好,但我想更快地运行它。 有什么建议吗?

5个回答

4

你的代码中涉及到了大量的装箱/拆箱操作,建议将 ArrayList<> 替换为对应的基本数据类型数组。


必须选择另一个答案作为正确答案,因为它甚至向我建议如何使更多的堆空间可用。 :-) - Kazekage Gaara
别担心 - 这一切都是为了解决问题! - dlev

3

通过不使用偶数,将速度提高一倍。


3

一种可能的优化方案是将ArrayList替换为基本类型的数组,前提是您事先知道所需数组的大小。这将有助于防止当前代码中存在的所有不必要的装箱/拆箱操作。

此外,请注意,您不必在数组中存储偶数,只需要存储奇数-这样做将减少内存需求并将处理时间减半。

为解决OutOfMemoryError,您可以在启动时调整JVM的配置参数,为应用程序提供更多的堆空间。


1
你的代码比必要的工作多得多。你只需要一个布尔数组,两个循环来标记非素数,另一个循环来打印素数的索引号。像这样:

public void printPrimes(int max) {

    // declare a single array of booleans
    boolean[] primeFlags = new boolean[max + 1];

    // double loop sieve-style and mark non-primes as true
    for (int m = 2; m <= (int)Math.sqrt(max); m++) 
        for (int k = m*m; k <= max; k += m) primeFlags[k] = true;

    // loop over bool array and print indexes with false values 
    // which will be the prime numbers
    for (int m = 2; m <= max; m++)
        if (!primeFlags[m]) System.out.print(m + " ");
}

0
import java.util.Scanner;

//Sieve Of Erastothenes

public class SieveOfErastothenes {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.print("Enter a range n : ");
        int n = sc.nextInt();

        boolean ar[] = new boolean[n+1];
        for (int i=2;i<=n;i++)
        ar[i] = true;

        for(int i = 2;i*i<=n;i++)
        {
            if(ar[i])
            {
                for(int j=i;i*j<=n;j++)
                    ar[i*j]=false;
            }
        }

        for(int i=2;i<=n;i++)
        {
            if(ar[i])
                System.out.print(i+" ");
        }
        sc.close();

    }

}

/*This code is contributed by Asish Samantaray*/

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接