【问题标题】:Improving efficiency of Sieve of Eratosthenes code in java提高java中埃拉托色尼筛法的效率
【发布时间】:2012-02-22 18:23:57
【问题描述】:

我使用 Java 编写了 Sieve of Eratosthenes 的代码,但我面临一些时间和空间效率问题。 这是代码:

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

【问题讨论】:

    标签: java performance sieve-of-eratosthenes


    【解决方案1】:

    您正在对该代码中的 ton 进行装箱/拆箱。您可能想尝试用原始类型的直接数组替换 ArrayList&lt;&gt;s。

    【讨论】:

    • 不得不选择另一个答案作为正确的答案,因为它甚至建议我如何使更多的堆空间可用。 :-)
    • 不用担心 - 一切都是为了解决问题!
    【解决方案2】:

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

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

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

    【讨论】:

      【解决方案3】:

      不使用偶数可将速度加倍。

      【讨论】:

        【解决方案4】:

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

        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 + " ");
        }
        

        【讨论】:

          【解决方案5】:
          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*/
          

          【讨论】:

            猜你喜欢
            • 2018-07-03
            • 2018-09-30
            • 1970-01-01
            • 2018-07-21
            • 2011-12-16
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多