筛选Eratosthenes ArrayIndexOutOfBounds

时间:2011-10-09 23:47:23

标签: java math sieve-of-eratosthenes

尝试用一个简单的erathosthenes筛来解决项目euler上的这个问题:

  

低于10的素数之和为2 + 3 + 5 + 7 = 17.

     

找出200万以下所有素数的总和。

Link

我的代码不断返回此错误:

  

线程“main”中的异常java.lang.ArrayIndexOutOfBoundsException:   Prime.main的-2147479015(Prime.java:28)

任何人都可以给我任何提示吗?这是代码:

import java.math.BigInteger;

public class Prime {
    /*
     * Input: an integer n > 1
     * 
     * Let A be an array of bool values, indexed by integers 2 to n, initially
     * all set to true.
     * 
     * for i = 2, 3, 4, ..., while i^2 ≤ n: if A[i] is true: for j = i^2, i^2 +
     * i, i^2 + 2i, ..., while j ≤ n: A[j] = false
     * 
     * Now all i such that A[i] is true are prime.
     */

        import java.math.BigInteger;

public class Prime {
    /*
     * Input: an integer n > 1
     * 
     * Let A be an array of bool values, indexed by integers 2 to n, initially
     * all set to true.
     * 
     * for i = 2, 3, 4, ..., while i^2 ≤ n: if A[i] is true: for j = i^2, i^2 +
     * i, i^2 + 2i, ..., while j ≤ n: A[j] = false
     * 
     * Now all i such that A[i] is true are prime.
     */

    public static void main(String[] args) {
        boolean[] array = new boolean[2000000];
        BigInteger counter = new BigInteger("0");
        for (int value = 0; value < array.length; value++) {
            array[value] = true;
        }
        for (int i = 2; i < array.length; i++) {
            if (array[i]) {
                int j = i * i;
                while (j > 0 && j < array.length) {
                    array[j] = false;
                    j += i;
                }
            }
        }
        for (int i = 2; i < array.length; i++) {
            if (array[i]) {
                counter = counter.add(BigInteger.valueOf(i));
            }
        }
        for (int value = 2; value < array.length; value++) {
            if(array[value]){
                System.out.println(value + ", ");
            }
        }
        System.out.println("\n" + counter);

    }

}

2 个答案:

答案 0 :(得分:4)

问题来自以下几点:

        int j = i * i;
        while (j <= array.length) {
            array[j] = false;
            j += i;
        }

正在发生的事情是,有时i * i是如此之大,以至于它绕过角落(溢出)并变为负面。 Java没有'检查'整数数学。要解决此问题,您需要将while条件更改为以下

while(j > 0 && j < array.length)

此外,您的阵列大小为200,000而不是2,000,000。

答案 1 :(得分:2)

不要太苛刻,但这是因为你已经超出了数组的范围。 i的限制是数组的长度,然后j至少等于i的平方。然后将j用作要在第28行访问的数组的位置,该数据超出范围。