计算素数直到N.

时间:2015-06-15 16:40:22

标签: java primes

此代码可以很好地计算素数直到n。问题是当n值大到1000000或更大时,则执行和打印输出需要很长时间(超过30秒)。我想解决这个问题。任何帮助都会很棒。 以下是代码:

public class PrimeNotillN {

        public static void main(String[] args) {

            int n = 1000;
            int count = 0;

            for (int i = 2; i < n; i++) {
                boolean res = checkprime(i);
                if (res == true)
                    count++;
            }
            System.out.println("total prime number till " + n + " is " + count);
        }

        private static boolean checkprime(int n) {
            if (n == 1)
                return false;
            else {
                for (int i = 2; i <= n / 2; i++) {
                    if (n % i == 0) {

                        return false;
                    }
                }

                return true;
            }
        }
    }

5 个答案:

答案 0 :(得分:2)

最简单的更改是在for达到checkprime的平方根后,在i中结束n循环。原因是如果你发现一个因子大于n的平方根,那就意味着有一个因子小于应该已经找到的n的平方根。

for (int i = 2; i <= Math.sqrt(n); i++) {

此外,如果您需要更高的速度,打印所有素数的最佳算法是Sieve of Eratosthenes。这涉及到取代你拥有的东西。你需要一个数组,你可以在其中标记哪些数字是复合数。从2开始,您将所有2的倍数标记为复合。在数组中移动,如果您找到一个未标记为复合的数字,则它是素数,您可以打印它。对于您遇到的每个素数,您将所有素数的倍数标记为复合。

答案 1 :(得分:1)

除了2之外,Primes从来都不是。 Primes只能被1和iteslef整除。

你也可以检查它的sqrt。如果你什么都没发现那么它就是一个黄金时期。

        public bool IsPrime(double num)
    {
        bool isprime = true;
        double limit = Math.Sqrt(num);

        if (num % 2 == 0)
            return num == 2;

        if (num == 3 || num == 5 || num == 7)
            return true;

        for (int i = 3; i < limit; i++)
            if (num % 1 == 0)
                return false;

        return isprime;
    }

答案 2 :(得分:0)

您可以将找到的素数存储到列表中并仅对它们进行进一步检查(Sieve of Eratosphenes):

import java.util.ArrayList;
import java.util.List;

public class PrimeNotillN {
    public static void main(String[] args) {
        int n = 1000000;
        int count = 0;
        List<Integer> primes = new ArrayList<>();

        for (int i = 2; i < n; i++) {
            boolean res = checkprime(primes, i);
            if (res) {
                count++;
                primes.add(i);
            }
        }
        System.out.println("total prime number till " + n + " is " + count);
    }

    private static boolean checkprime(List<Integer> primes, int n) {
        int fence = (int) Math.sqrt(n);
        for (int prime : primes) {
            if (n % prime == 0) {
                return false;
            }
            if (prime >= fence)
                break;
        }

        return true;
    }
}

答案 3 :(得分:0)

使用eratoshtenes方法的筛子并保持所有素数的缓存

    public int countPrimes(int n) {
    if(n==0){
        return 0;
    }else{
        boolean[] isPrime=new boolean[n];
        for(int i=2;i<n;i++){
            isPrime[i]=true;
        }

        for(int i=2;i*i<n;i++){
           if(!isPrime[i]){
               continue;
           }
            for(int j=i*i;j<n;j+=i){
                isPrime[j]=false;
            }
        }

        int counter=0;
        for(int i=2;i<n;i++){
            if(isPrime[i]){
                counter++;
            }
        }

        return counter;

    }
}

答案 4 :(得分:0)

Eratosthenes筛是一种非常著名且高效的算法,它可以生成所有小质数,最多可达1到1千万。这是希腊数学家名为Eratosthenes的古老算法。

 public class CountPrimes {

  public static void main(String[] args) {
    System.out.println(countPrimes(1000000));
  }

  public static int countPrimes(int n) {
    boolean[] primes = new boolean[n +1];

    for(int i = 0 ; i <= n ; i++) {
        primes[i] = true;
    }

    primes[0] = false;
    primes[1] = false;

    for(int i = 2 ; i * i <= n ; i++) {
        if(primes[i]) {
            for(int j = i ; i * j <= n ; j++) {
                primes[j * i ] = false;
            }
        }   
    }

    int primeCounts = 0;
    for(int i = 2 ; i <= n ; i++) {
        if(primes[i]) {
            primeCounts++;
        }
    }

    return primeCounts;
  }

}