在Java中,代码不会停止运行

时间:2014-05-19 07:54:23

标签: java primes

我在Java中的项目Euler中解决问题10,这是

  

“10以下的素数之和为2 + 3 + 5 + 7 = 17   找出200万以下所有素数的总和。“

我的代码是

package projecteuler_1;

import java.math.BigInteger;
import java.util.Scanner;

public class ProjectEuler_1 {

 public static void main(String[] args) {
    int sum = 0, i = 2;
    while (i <= 2000000) {
        if (isPrime(i)) {
            sum += i;
        }
        i++;
    }
    System.out.println(sum);
 }

 public static boolean isPrime(int n) {
    int i, res;
    boolean flag = true;
    for (i = 2; i <= n / 2; i++) {
        res = n % i;
        if (res == 0) {
            flag = false;
            break;
        }
    }
    return flag;
 }
}

但代码没有给我任何结果,它不会停止运行。为什么呢?

2 个答案:

答案 0 :(得分:2)

通过稍作改动,您可以极大地提高性能:

变化:

for (int i = 2; i < n; i++) {

要:

int max = Math.sqrt(n);
for (int i = 2; i <= max; i++) {

您只需要检查数字的平方根,因为在上升过程中已经找到了更大的因子。

进行此更改会将您的算法从O(n 2 )更改为O(n log(n))(我认为)。您的代码不会输出任何内容,因为它需要花费太长时间才能运行 - 更改应该可以在合理的时间内为您提供答案。

答案 1 :(得分:0)

您的代码运行时间为O(n^2)。每次对isPrime()的调用平均为O(n)

<强>解释

1/2的数字可以除以2,1/3可以除以3,... 1/n可以被n除。此方法的预期运行次数将为(1-1/2) + (1-1/3) +...+(1-1/n) = (1+1+..+1)-(1/2+1/3+..+1/n) = n - (1/2+1/3+...+1/n)第二个和为harmonic number,其总和为O(logn),因此这将为您提供O(n-logn)=O(n)运行时间。

由于这是按照每个号码完成的,因此它总计O(n^2)


@Bohemian更改为int max = Math.sqrt(n);的方法将产生O(nsqrt(n))效果,如in this thread所述。


时间复杂度方面的最佳方法是使用类似 Sieve of Eratosthenes 的内容,这会产生O(nlogn)时间性能,这比您的算法渐近地好,并且优化的一个,因此对于大数字来说会更快地运行。

相关问题