8

Given an integer M. return all prime numbers smaller than M.

Give a algorithm as good as you can. Need to consider time and space complexity.

Cœur
  • 37,241
  • 25
  • 195
  • 267
user658266
  • 2,397
  • 4
  • 20
  • 14

9 Answers9

18

The Sieve of Eratosthenes is a good place to start.

http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes

Andrew Cooper
  • 32,176
  • 5
  • 81
  • 116
  • 2
    There are other sieves that are easy to understand and don't demand O(n) space. Or you just do it for a constant amount of numbers over and over. Eg. you want all primes below 10000 then do it in batches of 100 or 1000 to reduce space usage and only save the primes afterwards. – HopefullyHelpful May 05 '16 at 12:01
  • O(n) space is a lot of space complexity if N is higher, may be 2 billion or more than that. The Sieve of Atkin is the best to use. – Krish Bhanushali Jan 31 '18 at 22:05
12

A couple of additional performance hints:

  1. You only need to test up to the square root of M, since every composite number has at least one prime factor less than or equal to its square root
  2. You can cache known primes as you generate them and test subsequent numbers against only the numbers in this list (instead of every number below sqrt(M))
  3. You can obviously skip even numbers (except for 2, of course)
Wayne
  • 59,728
  • 15
  • 131
  • 126
  • 11
    3. Well, you shouldn't drop all of them! You shouldn't drop 2 ;-) – Curd Mar 18 '11 at 09:59
  • 3
    I think first statement is wrong. For example N = 120. 113 is prime < N. but 113 > sqrt (N). – Juan Carlos Oropeza Apr 20 '15 at 16:32
  • 4
    I'm not sure what you're trying to say. Of course there could be (unrelated) primes greater than the square root of *N*, but that doesn't tell us anything useful. The point is that every composite number has at least one prime factor less than or equal to its square root and you only need to find one such factor to prove that *N* is composite (i.e. there's no need to continue checking). That's the point of the first statement. – Wayne Apr 20 '15 at 17:13
  • Sorry. I think is maybe your answer is short and looks like a comment instead of a complete answer. When i read the Wiki Sieve of Eratosthenes I understand your tip. But because your answer was first thing I read didn't understand what was you talking about. – Juan Carlos Oropeza Apr 20 '15 at 18:20
  • The Sieve of Eratosthenes is not necessary for understanding the mathematical fact that all composite numbers have at least one prime factor less than or equal to their square root. My answer has nothing to do with the Sieve of Eratosthenes. What I'm describing is a method for eliminating many iterations when checking for primes. I'm afraid your comments here are not helping. – Wayne Apr 20 '15 at 18:54
  • 1
    You are correct, But you need to understand the context to apply that fact. I'm not saying your answer is wrong, but I didnt understand it until I got the context from the other answer I was just suggesting to improve your answer a little bit so other users get a better understanding, for example I confuse your N with OP M. Also just realize even when your was the accepted answer the one from Andrew is the most voted because give othrer users looking for answer the right context. – Juan Carlos Oropeza Apr 22 '15 at 17:07
2

Sieve of Eratosthenes is good.

Asaph
  • 159,146
  • 25
  • 197
  • 199
user664982
  • 51
  • 5
2

The usual answer is to implement the Sieve of Eratosthenes, but this is really only a solution for finding the list of all prime numbers smaller than N. If you want primality tests for specific numbers, there are better choices for large numbers.

Community
  • 1
  • 1
sarnold
  • 102,305
  • 22
  • 181
  • 238
0

i'm a novice programmer in c# (and new to S.O.), so this may be a bit verbose. nevertheless, i've tested this, and i works.

this is what i've come up with:

for (int i = 2; i <= n; i++)
{
    while (n % i == 0)
    {
        Console.WriteLine(i.ToString());
        n /= i;
    }
}
Console.ReadLine();
0

π(n) count the primes less than or equal to n. Pafnuty Chebyshev has shown that if

limn→∞ π(n)/(n/ln(n))

exists, it is 1. There are a lot of values that are approximately equal to π(n) actually, as shown in the table.

enter image description here

It gives right number of prime number for this number format.I hope this will be helpful.

Ujjwal
  • 346
  • 4
  • 11
0

You can do it using a bottom up dynamic programming approach called the Sieve of Eratosthenes Basically you create a boolean cache of all numbers upto n and you mark each the multiples of each number as not_prime. Further optimizations can be gained by checking only upto sqrt(n) since any composite number will have at least one divisor less that sqrt(n)

    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;
        }

        /* Using i*i<n instead of i<Math.sqrt(n)
         to avoid the exepnsive sqrt operation */
        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;

    }
}
Mad Scientist
  • 340
  • 4
  • 14
0

This is what I developed for Seive of Eratosthenes. There would be better implementations,of course.

//finds number of prime numbers less than length

private static int findNumberOfPrimes(int length) {
    int numberOfPrimes = 1;
    if (length == 2) {
        return 1;
    }

    int[] arr = new int[length];
    //creating an array of numbers less than 'length'
    for (int i = 0; i < arr.length; i++) {
        arr[i] = i + 1;
    }
    //starting with first prime number 2, all the numbers divisible by 2(and upcoming) is replaced with -1
    for (int i = 2; i < arr.length && arr[i] != -1; i++) {

        for (int j = i; j < arr.length; j++) {
            if (arr[j] % arr[i] == 0) {
                arr[j] = -1;
                numberOfPrimes += 1;
            }
        }

    }
    return numberOfPrimes;
}
Tunaki
  • 132,869
  • 46
  • 340
  • 423
Vikash
  • 711
  • 1
  • 11
  • 19
0

The Sieve of Atkin is also the best algorithm to implement in this case and it takes only O(N) operations and O(N) space. Please refer https://en.wikipedia.org/wiki/Sieve_of_Atkin for detailed explanation of the algorithm and pseudocode.

Krish Bhanushali
  • 170
  • 1
  • 1
  • 8