输出不大于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

原文地址:https://www.cnblogs.com/learning-c/p/5203816.html