求n以内素数个数多种方法时间复杂度对比

import java.util.Scanner;

public class PrimeNumber {

    /**
     * 穷举法,检测所有可能的因子。
     * 时间复杂度为:O(n^2)
     */
    public void primeNumber1(int n) {
        int number = 2;
        int count = 0;
        while(number <= n) {
            boolean isPrime = true;
            for(int divisor = 2; divisor <= number / 2; divisor++) {
                if(number % divisor == 0) {
                    isPrime = false;
                    break;
                }
            }
            if(isPrime) {
                count++;
            }
            number++;
        }
        System.out.println("\ncount: " + count);
    }

    /**
     * 检测直到√n的因子
     * 时间复杂度为:O(n√n)
     */
    public void primeNumber2(int n) {
        int number = 2;
        int count = 0;
        while(number <= n) {
            boolean isPrime = true;
            int squareRoot = (int) Math.sqrt(number);
            for(int divisor = 2; divisor <= squareRoot; divisor++) {
                if(number % divisor == 0) {
                    isPrime = false;
                    break;
                }
            }
            if(isPrime) {
                count++;
            }
            number++;
        }
        System.out.println("\ncount: " + count);
    }

    /**
     * 检测直到√n的素数因子
     * 简易证明:如果i不是素数,那就必须存在一个素数p,满足i=pq且p<=q。
     * k也是i的最小因子,这和p是i的最小因子是冲突的。因此,如果i不是素数,
     * 那么可以找出2到√i之间的被i整除的素数。
     * 时间复杂度为:O(n√n / logn)
     */
    public void primeNumber3(int n) {
        int number = 2;
        int count = 0;
        int squareRoot = 1;
        int[] primes = new int[n];
        while(number <= n) {
            boolean isPrime = true;
            if(squareRoot * squareRoot < number) {
                squareRoot++;
            }
            for(int k = 0; k < count && primes[k] <= squareRoot; k++) {
                if(number % primes[k] == 0) {
                    isPrime = false;
                    break;
                }
            }
            if(isPrime) {
                primes[count] = number;
                count++;
            }
            number++;
        }
        System.out.println("\ncount: " + count);
    }

    /**
     * 埃拉托色尼筛选算法,该方法效率最高,但空间开销比较大
     * 时间复杂度为:O(n√n / logn)
     */
    public void primeNumber4(int n) {
        boolean[] primes = new boolean[n + 1];
        for(int i = 0; i < primes.length; i++) {
            primes[i] = true;
        }
        for(int k = 2; k <= n / k; k++) {
            if(primes[k]) {
                for(int i = k; i <= n / k; i++) {
                    primes[k * i] = false;
                }
            }
        }
        int count = 0;
        for(int i = 2; i < primes.length; i++) {
            if(primes[i]) {
                count++;
            }
        }
        System.out.println("\ncount :" + count);
    }

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        System.out.println("Find all prime numbers <= n,enter n:");
        int n = input.nextInt();

        long start = 0;
        long end = 0;

        start = System.currentTimeMillis();
        new PrimeNumber().primeNumber1(n);
        end = System.currentTimeMillis();

        System.out.printf("primeNumber1 所用时间为(单位毫秒):%d\n", end - start);

        start = System.currentTimeMillis();
        new PrimeNumber().primeNumber2(n);
        end = System.currentTimeMillis();

        System.out.printf("primeNumber2 所用时间为(单位毫秒):%d\n", end - start);

        start = System.currentTimeMillis();
        new PrimeNumber().primeNumber3(n);
        end = System.currentTimeMillis();

        System.out.printf("primeNumber3 所用时间为(单位毫秒):%d\n", end - start);

        start = System.currentTimeMillis();
        new PrimeNumber().primeNumber4(n);
        end = System.currentTimeMillis();

        System.out.printf("primeNumber4 所用时间为(单位毫秒):%d\n", end - start);
    }
}

n = 10000

Find all prime numbers <= n,enter n:
10000

count: 1229
primeNumber1 所用时间为(单位毫秒):42

count: 1229
primeNumber2 所用时间为(单位毫秒):3

count: 1229
primeNumber3 所用时间为(单位毫秒):1

count :1229
primeNumber4 所用时间为(单位毫秒):0

n = 100000

Find all prime numbers <= n,enter n:
100000

count: 9592
primeNumber1 所用时间为(单位毫秒):782

count: 9592
primeNumber2 所用时间为(单位毫秒):15

count: 9592
primeNumber3 所用时间为(单位毫秒):8

count :9592
primeNumber4 所用时间为(单位毫秒):4

n = 1000000

Find all prime numbers <= n,enter n:
1000000

count: 78498
primeNumber1 所用时间为(单位毫秒):62873

count: 78498
primeNumber2 所用时间为(单位毫秒):220

count: 78498
primeNumber3 所用时间为(单位毫秒):50

count :78498
primeNumber4 所用时间为(单位毫秒):18

猜你喜欢

转载自blog.csdn.net/XlxfyzsFdblj/article/details/81149668
今日推荐