对于与质数有关的所有内容,我都开设了一个称为素数的课程。它包含一个名为isPrime的方法,该方法使用另一个名为sieveOfAtkin的方法来创建一个名为sieve的布尔数组,该数组的索引值为0到1000000。用户将整数n传递给isPrime方法。如果sieve [n] = true,则整数n是质数。否则isPrime返回false。我的问题是,当我使用我知道的质数测试此方法时,它总是返回false。以下面这行代码为例,该代码测试13是否为质数:

public class Test {
 public static void main(String[] args) {
  Primes pr=new Primes(); // Creates Primes object
  System.out.println(pr.isPrime(13));
 }
}


即使我们知道13是质数,输出也将是错误的。这是我整个Primes类https://github.com/javtastic/project_euler/blob/master/Primes.java的代码

它使用atkin筛子,该筛子被认为是测试素数的最有效方法。有关更多信息,请参见:http://en.wikipedia.org/wiki/Sieve_of_Atkin

我不确定自己在做什么错。我已经尝试了几个小时才能找出导致此错误的原因,但我仍然得到相同的结果(一切都是假的)。也许我应该找到一种检查素数的其他方法?

最佳答案

该代码对我来说就像一个魅力,无需更改。



import java.util.Arrays;

public class Test {
    // This class uses a Atkin sieve to determine all prime numbers less than int limit
    // See http://en.wikipedia.org/wiki/Sieve_of_Atkin
    private static final int       limit     = 1000000;
    private final static boolean[] sieve     = new boolean[limit + 1];
    private static int             limitSqrt = (int) Math.sqrt(limit);

    public static void sieveOfAtkin() {
        // there may be more efficient data structure
        // arrangements than this (there are!) but
        // this is the algorithm in Wikipedia
        // initialize results array
        Arrays.fill(sieve, false);
        // the sieve works only for integers > 3, so
        // set these trivially to their proper values
        sieve[0] = false;
        sieve[1] = false;
        sieve[2] = true;
        sieve[3] = true;
        // loop through all possible integer values for x and y
        // up to the square root of the max prime for the sieve
        // we don't need any larger values for x or y since the
        // max value for x or y will be the square root of n
        // in the quadratics
        // the theorem showed that the quadratics will produce all
        // primes that also satisfy their wheel factorizations, so
        // we can produce the value of n from the quadratic first
        // and then filter n through the wheel quadratic
        // there may be more efficient ways to do this, but this
        // is the design in the Wikipedia article
        // loop through all integers for x and y for calculating
        // the quadratics
        for (int x = 1 ; x <= limitSqrt ; x++) {
            for (int y = 1 ; y <= limitSqrt ; y++) {
                // first quadratic using m = 12 and r in R1 = {r : 1, 5}
                int n = (4 * x * x) + (y * y);
                if (n <= limit && (n % 12 == 1 || n % 12 == 5)) {
                    sieve[n] = !sieve[n];
                }
                // second quadratic using m = 12 and r in R2 = {r : 7}
                n = (3 * x * x) + (y * y);
                if (n <= limit && (n % 12 == 7)) {
                    sieve[n] = !sieve[n];
                }
                // third quadratic using m = 12 and r in R3 = {r : 11}
                n = (3 * x * x) - (y * y);
                if (x > y && n <= limit && (n % 12 == 11)) {
                    sieve[n] = !sieve[n];
                }
                // note that R1 union R2 union R3 is the set R
                // R = {r : 1, 5, 7, 11}
                // which is all values 0 < r < 12 where r is
                // a relative prime of 12
                // Thus all primes become candidates
            }
        }
        // remove all perfect squares since the quadratic
        // wheel factorization filter removes only some of them
        for (int n = 5 ; n <= limitSqrt ; n++) {
            if (sieve[n]) {
                int x = n * n;
                for (int i = x ; i <= limit ; i += x) {
                    sieve[i] = false;
                }
            }
        }
    }

    // isPrime method checks to see if a number is prime using sieveOfAtkin above
    // Works since sieve[0] represents the integer 0, sieve[1]=1, etc
    public static boolean isPrime(int n) {
        sieveOfAtkin();
        return sieve[n];
    }

    public static void main(String[] args) {
        System.out.println(isPrime(13));
    }
}

Input - 13, Output - True
Input -23, Output - True
Input - 33. output - False

10-06 03:01