对于与质数有关的所有内容,我都开设了一个称为素数的课程。它包含一个名为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