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。代码似乎工作正常,但我想把它再固定一点。有什么建议么?

4

5 回答 5

4

您正在对该代码进行大量装箱/拆箱。您可能想尝试将ArrayList<>s 替换为原始类型的直接数组。

于 2012-02-22T18:29:25.633 回答
3

通过不使用偶数来加倍速度。

于 2012-02-22T18:32:15.143 回答
3

一种可能的优化是将 ArrayLists 替换为原始类型的数组,前提是您事先知道所需数组的大小。这将具有防止代码中当前存在的所有不必要的值装箱/拆箱的效果。

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

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

于 2012-02-22T18:34:45.533 回答
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 + " ");
}
于 2012-02-22T20:13:07.207 回答
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*/
于 2016-12-30T04:41:46.113 回答