【问题标题】:Find the prime-->sieve way找到素数-->筛法
【发布时间】:2012-09-26 19:52:03
【问题描述】:

我尝试了几次,但仍然给了我 ArrayOutOfIndex。但我想节省内存,所以我使用

boolean[]isPrime = new boolean [N/2+1];

而不是

boolean[]isPrime = new boolean [N+1];

这给了我第 23 和 47 行的 ArrayOutOfIndex

第 23 行:

    for (int i = 3; i <= N; i=i+2) {
    isPrime[i] = true;
    }

第 47 行:

  for (int i = 3; i <= N; i=i+2) {
        if (isPrime[i]) primes++;
  ...
   }

Full code:

public class PrimeSieve {
    public static void main(String[] args) { 

        if (args.length < 1) {
            System.out.println("Usage: java PrimeSieve N [-s(ilent)]");
            System.exit(0);
        }

        int N = Integer.parseInt(args[0]);

        // initially assume all odd integers are prime

        boolean[]isPrime = new boolean [N/2+1];

        isPrime[2] = true;

        for (int i = 3; i <= N; i=i+2) {
            isPrime[i] = true;
        }

        int tripCount = 0;

        // mark non-primes <= N using Sieve of Eratosthenes
        for (int i = 3; i * i <= N; i=i+2) {

            // if i is prime, then mark multiples of i as nonprime
        if (isPrime[i]) {
          int j = i * i;
          while (j <= N){
            tripCount++;
            isPrime[j] = false;
            j = j + 2*i;
            }
                        }
                                            }

        System.out.println("Number of times in the inner loop: " + tripCount);

        // count and display primes
        int primes = 0;
        if(N >= 2 ){
            primes = 1;
        }
        for (int i = 3; i <= N; i=i+2) {
            if (isPrime[i]) primes++;
            if (args.length == 2 && args[1].equals("-s"))
                ; // do nothing
            else
                System.out.print(i + " ");
        }
        System.out.println("The number of primes <= " + N + " is " + primes);
    }
}

【问题讨论】:

  • 如果你想节省内存,使用位数组而不是boolean[]会节省更多。

标签: java algorithm primes sieve-of-eratosthenes


【解决方案1】:

您应该使用相同的索引函数来存储和访问数组:isPrime[i/2]

【讨论】:

  • 非常感谢!像魅力一样工作!
【解决方案2】:

当您将数组的大小从 [N+1] 更改为 [N/2+1] 时,您还需要更新 for 循环的结束条件。现在你的for循环一直运行到i=N,所以你尝试在i &gt; (N/2+1)时执行isPrime[i] ...所以你得到一个ArrayIndexOutOfBoundsException

改变这个:

for (int i = 3; i <= N; i=i+2) 

到这里:

for (int i = 3; i <= N/2; i=i+2) 

【讨论】:

  • 需要注意的是,它应该严格小于 N/2+1,否则你会得到一个 IndexOutOfBoundsException
  • 但这反而给了我错误的答案....太奇怪了...如果我将所有 N/2+1 改回 N,它会给我正确的答案..
  • @jzhong5 - 那么你的代码是错误的。这只是防止ArrayIndexOutOfBoundsException 发生。
【解决方案3】:

好吧,例如,如果 N=50,您的 isPrime 仅包含 26 个元素,并且您尝试访问 3、5..47、49 处的元素(当然,这是超出范围的)

你可能想要的是在你的循环中使用i/2(作为索引),这样你仍然在迭代数字 3,5..47,49,但是你使用向量的正确索引。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-14
    • 2016-11-18
    • 1970-01-01
    相关资源
    最近更新 更多