求小于N的所有素数的和
/**
* The sum of the primes below 10 is 2 + 3 + 5 + 7 = 17.
*
* Find the sum of all the primes below two million.
*/
思路:
个人只会傻逼的遍历判断这个数是否为素数,然后迭加,代码如下:
View Code
private static long sumPrime(int N) { if (N < 2) return 0; if (N == 2) return 2; long sum = 2; for (int i = 3; i <= N; i += 2) { if (isPrime(i)) sum += i; } return sum; }
但是官网的参考答案学得一个很有意思的做法,利用素数筛来做,其基本思想如下:
1、一个合数必然是其他素数因子的乘积,great,原来从没注意到这点。
2、那么可以利用一个长度大小为n的数组a来表示n是否为素数,首先全初始化为一个初值,例如0,
3、然后从依次从最小的素数p迭代,对于这个素数p的倍数的a[p*m]置为1,表明从这个数不是素数,从素数集合筛选掉
4、同时注意3中当m=2*n时时,这个数必然是偶数,那么不是素数,则迭代一次可以递增2p,可以减少迭代步骤
代码如下:
View Code
private static long sumPrimeSieve(int N) { long sum = 0; boolean sieve[] = new boolean[N]; for (int i = 0; i < N; i++) sieve[i] = false; for (int i = 4; i < N; i += 2) sieve[i] = true; for (int i = 3; i * i <= N; i = i + 2) { if (!sieve[i]) { for (int j = i * i; j < N; j += 2 * i) sieve[j] = true; } } for (int n = 2; n < N; n++) if (!sieve[n]) sum += n; return sum; }
官网上还有一个优化的算法,主要为了减少空间而设计,这里不再列出