输出不大于N的素数的个数
输出不大于N的素数的个数
Sieve of Eratosthenes 方法
素数的性质: 非素数可以分解为素数乘积。
证明 (1)n = 2 成立,n = 3 成立;
(2)若 n = k 时成立,n = k+1时,假设 n = k+1 = k1*k2, 如果 k+1 是素数,k1 = 1, k2 = K+1, 成立;
如果 k+1不是素数,k1 <= k, k2 <= k, 两者都可以表示为素数乘积,所以 k+1可以表示为素数乘积。
其它细节见程序注释,
public class PrimeSieve { public static void main(String[] args) { int N = Integer.parseInt(args[0]); // initially assume all integers are prime boolean[] isPrime = new boolean[N + 1]; for (int i = 2; i <= N; i++) { isPrime[i] = true; } // mark non-primes <= N using Sieve of Eratosthenes for (int i = 2; i*i <= N; i++) { // 假设 N = k1 * k2, k1 和 k2 中一定有一个是小于等于 sqrt(N) 的,所以只要考虑 i 属于 [2..floor(sqrt(N))]就可以了 // if i is prime, then mark multiples of i as nonprime ** 如果 i 是素数,那么将 i 的倍数都标记为非素数 // suffices to consider mutiples i, i+1, ..., N/i ** j 最小是 i, 因为执行到这一步,已经排除了以 [2..i-1] 为因数的非素数。 2*i,3*i,4*i,...,(i-1)*i 都已经被排除了。 j 最大是 N/i, 因为要保证 i * j <= N if (isPrime[i]) { // for (int j = i; i*j <= N; j++) { isPrime[i*j] = false; } } } // count primes int primes = 0; for (int i = 2; i <= N; i++) { if (isPrime[i]) primes++; } System.out.println("The number of primes <= " + N + " is " + primes); } }
运行结果: 小于 25的素数的个数 pi(25) = 9, 分别是 2 3 5 7 11 13 17 19 23