什么是快速添加数千个数字的有效方法?

时间:2016-10-09 01:45:25

标签: java modulo addition modular-arithmetic

我正试图解决一个挑战,但我遇到了障碍。我是一名初学者,试图添加成千上万的数字。如果我等待足够长的时间,我的程序可以很容易地得到正确的总和,但是,我正在寻找一种更有效的方法。

快速添加数千个数字的有效方法是什么?

旁注:我一直在阅读关于模运算的内容,但我无法完全理解它。不确定这对这种情况是否有用。

我试图得到每个素数低于2 000 000的总和。到目前为止,这是我的代码:

public class Problem10 {
    public static void main (String[] args) {
        long sum = 0L;

        for(long i = 1L; i < 2000000; i++) {
            if(isPrimeNumber((int)i)) {
                sum += i;
            }
        }
        System.out.println(sum);
    }

    public static boolean isPrimeNumber(int i) {
        int factors = 0;
        int j = 1;

        while (j <= i) {
            if (i % j == 0) {
                factors++;
            }
            j++;
        }
        return (factors == 2);
    }
}

2 个答案:

答案 0 :(得分:2)

这看起来像是家庭作业,所以我不打算在代码中给你解决方案。你能做的最少就是自己编写代码。

在你的代码中,isPrimeNumber()占据了大部分时间 - 如果我不得不猜测,我会说90-99%。你可以做些什么来加快速度,实现Sieve of Eratosthenes

首先,创建一个包含所有素数 1 的数组。您应该使用单个值启动它:2。要查找更多素数,请迭代从3到您想要的最大数字的每个整数。对于这些数字中的每一个,检查该数字是否可被数组中的任何素数整除。如果数组中的下一个素数大于i / 2,则表示i为素数,您可以将其添加到数组中。

在找到从1到n的所有素数后,求它们的唯一方法是迭代数组。那部分无法优化,但反正不会花很长时间。

1 有两种方法可以做到这一点。一种是使用ArrayList或LinkedList,并根据需要添加数字。另一种是创建一个比你需要的更大或更大的数组。如上所述here,等于或小于n的素数的数量小于(n / log(n)) * (1 + 1.2762 / log(n)),只要n大于598.如果n小于598,则可以创建一个数组长度109.

关于标题中的问题,“快速添加数千个数字的有效方法是什么?”,我唯一能想到的就是多线程。创建一个包含所有数字的数组,然后将多个线程相加到数组的不同部分。之后,汇总每个线程的所有结果。在对大量数字求和时,例如,这种方法可能只会明显更快。数十万或数百万。

答案 1 :(得分:2)

您可以使用此方法替换isPrimeNumber()方法以大幅加快速度。

public static boolean isPrimeNumber(int i) {
    if (i==2) return true;
    if (i==3) return true;
    if (i%2==0) return false;
    if (i%3==0) return false;

    int j = 5;
    int k = 2;

    while (j * j <= i) {
        if (i % j == 0) return false;
        j += k ;
        k = 6 - k;

    }
    return true;
}