Class that checks for primes not working properly
对于与质数有关的所有内容,我都开设了一个名为"素数"的课程。它包含一个名为isPrime的方法,该方法使用另一个名为sieveOfAtkin的方法来创建一个名为sieve的布尔数组,该数组的索引值为0到1000000。用户将整数n传递给isPrime方法。如果sieve [n] = true,则整数n是质数。否则isPrime返回false。我的问题是,当我使用我知道的质数测试此方法时,它总是返回false。以下面这行代码为例,该代码测试13是否为质数:
1 2 3 4 5 6 |
即使我们知道13是质数,输出也将是错误的。这是我整个Primes类的代码https://github.com/javtastic/project_euler/blob/master/Primes.java
它使用atkin筛子,该筛子被认为是测试素数的最有效方法。有关更多信息,请参见:http://en.wikipedia.org/wiki/Sieve_of_Atkin
我不确定自己在做什么错。我已经尝试了几个小时才能找出导致此错误的原因,但我仍然得到相同的结果(一切都是假的)。也许我应该找到一种检查素数的其他方法?
用这个:
1 2 3 4 5 6 7 8 9 | public static boolean isPrime(int number) { int sqrt = (int) Math.sqrt(number) + 1; for (int i = 2; i < sqrt; i++) { if (number % i == 0) { return false; } } return true; } |
该代码对我来说就像一个魅力,无需更改。
码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | 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 |