提高Sieve方法的性能

时间:2015-02-25 19:04:26

标签: java queue sieve

我正在编写一种方法来查找最多n的素数(Sieve of Eratosthenes),是的,这是用于作业。我希望通过我编写的方法提高性能。我在过去的几天里一直在调整它,但我无法遵循给出的伪代码并提高性能。

伪码如下:
创建一个数字队列来处理
用整数2到n(包括两个)填充队列 创建一个空结果队列来存储素数
重复以下步骤:
通过从数字队列中删除第一个值来获得下一个素数 将p放入素数的结果队列中 循环遍历数字队列,消除所有可被p整除的数字 而(p小于n的平方根)
所有剩余的值都是素数,因此将它们转移到素数结果队列

这是我目前的方法:

 public static Queue<Integer> getPrimes(int n) throws IllegalArgumentException
{
    if (n<2)
    {
        throw new IllegalArgumentException();
    }

    Queue<Integer> integers = new LinkedList<Integer>();
    Queue<Integer> primes = new LinkedList<Integer>();
    for (int i = 2; i <= n ; i++) {
        integers.add(i);
    }
    boolean[] isMultiple = new boolean[n + 1];

    for(int iterate = integers.remove(); iterate <= n; iterate++)
    {

        if(!isMultiple[iterate])
        {
            primes.add(iterate);
            for(int multiples = iterate * iterate; multiples >= 0 && multiples <= n; multiples += iterate)
            {
                isMultiple[multiples] = true;
            }
        }
    }
    return primes;
}

2 个答案:

答案 0 :(得分:3)

您可以先用两种方式对其进行优化: 1)您不需要integer链接列表。而是使用简单的for循环。

2)一旦你使用for循环,你可以先删除所有偶数,因为它们显然可被2整除。然后只是遍历奇数。从而将循环减少到一半。

代码段:

    primes.add(2);
    for(int i=2;i*i<=n;i++)
    {
        isMultiple[2*i]=true;
    }
    for(int i=3;i*i<=n;i+=2)
    {
        if(!isMultiple[i]) 
        {
            primes.add(i);
            for(int j=i*i;j<n;j+=i)
            {
               isMultiple[j]=true;
            }
        }
    }
    return primes;

答案 1 :(得分:0)

作为第一个小步骤,您可以移除integers队列并将其替换为常见的for循环:

for (int iterate = 2; iterate < n; iterate++)
{
     if (!isMultiple[iterate]) 
     {
         ...
     }
}