Sieve of Eratosthenes: Find All Primes Efficiently

Sanjeev SharmaSanjeev Sharma
3 min read

Advertisement

Sieve of Eratosthenes

Mark composite numbers by iterating multiples of each prime from 2 to sqrt(n).

Algorithm

Create boolean array is_prime[0..n], all True
Set is_prime[0] = is_prime[1] = False
For p = 2 to sqrt(n):
    if is_prime[p]:
        for multiple = p*p to n step p:
            is_prime[multiple] = False
Primes = {i : is_prime[i] is True}

Why start at p*p? Smaller multiples (2p, 3p, ...) already marked by smaller primes.

C Implementation

#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <math.h>

void sieve(int n, bool *is_prime) {
    for (int i = 0; i <= n; i++) is_prime[i] = true;
    is_prime[0] = is_prime[1] = false;
    for (int p = 2; p * p <= n; p++) {
        if (is_prime[p]) {
            for (int m = p * p; m <= n; m += p)
                is_prime[m] = false;
        }
    }
}

int main() {
    int n = 50;
    bool is_prime[51];
    sieve(n, is_prime);
    printf("Primes up to %d: ", n);
    for (int i = 2; i <= n; i++)
        if (is_prime[i]) printf("%d ", i);
    printf("\n");
    return 0;
}

C++ Implementation

#include <bits/stdc++.h>
using namespace std;

vector<int> sieve(int n) {
    vector<bool> is_prime(n + 1, true);
    is_prime[0] = is_prime[1] = false;
    for (int p = 2; (long long)p * p <= n; p++) {
        if (is_prime[p]) {
            for (int m = p * p; m <= n; m += p)
                is_prime[m] = false;
        }
    }
    vector<int> primes;
    for (int i = 2; i <= n; i++)
        if (is_prime[i]) primes.push_back(i);
    return primes;
}

int main() {
    auto primes = sieve(50);
    for (int p : primes) cout << p << " ";
    cout << endl;
    return 0;
}

Java Implementation

import java.util.*;

public class Sieve {
    public static List<Integer> sieve(int n) {
        boolean[] isPrime = new boolean[n + 1];
        Arrays.fill(isPrime, true);
        isPrime[0] = isPrime[1] = false;
        for (int p = 2; (long) p * p <= n; p++) {
            if (isPrime[p]) {
                for (int m = p * p; m <= n; m += p)
                    isPrime[m] = false;
            }
        }
        List<Integer> primes = new ArrayList<>();
        for (int i = 2; i <= n; i++)
            if (isPrime[i]) primes.add(i);
        return primes;
    }

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

JavaScript Implementation

function sieve(n) {
    const isPrime = new Array(n + 1).fill(true);
    isPrime[0] = isPrime[1] = false;
    for (let p = 2; p * p <= n; p++) {
        if (isPrime[p]) {
            for (let m = p * p; m <= n; m += p)
                isPrime[m] = false;
        }
    }
    return Array.from({length: n - 1}, (_, i) => i + 2).filter(i => isPrime[i]);
}

console.log(sieve(50));

Python Implementation

def sieve(n):
    is_prime = [True] * (n + 1)
    is_prime[0] = is_prime[1] = False
    p = 2
    while p * p <= n:
        if is_prime[p]:
            for m in range(p * p, n + 1, p):
                is_prime[m] = False
        p += 1
    return [i for i in range(2, n + 1) if is_prime[i]]

print(sieve(50))  # [2, 3, 5, 7, 11, 13, ...]

Smallest Prime Factor (SPF) Sieve

Enables O(log n) factorization after O(n log log n) build:

def spf_sieve(n):
    spf = list(range(n + 1))
    for p in range(2, int(n**0.5) + 1):
        if spf[p] == p:  # p is prime
            for m in range(p * p, n + 1, p):
                if spf[m] == m:
                    spf[m] = p
    return spf

def factorize(n, spf):
    factors = []
    while n > 1:
        factors.append(spf[n])
        n //= spf[n]
    return factors

Complexity

  • Time: O(n log log n)
  • Space: O(n)

Advertisement

Sanjeev Sharma

Written by

Sanjeev Sharma

Full Stack Engineer · E-mopro