Sito Eratostenesa

Algorytm Sito Eratostenesa jest klasycznym algorytmem do znajdowania wszystkich liczb pierwszych mniejszych niż pewna dana liczba n. Działa on w sposób iteracyjny, eliminując wielokrotności liczb pierwszych, aż do pozostawienia wyłącznie liczb pierwszych.

Kroki działania algorytmu Sito Eratostenesa

1. Inicjalizacja
Tworzymy listę liczby o długości n+1 (ponieważ sprawdzamy liczby od 0 do n), w której każda pozycja początkowo przyjmuje wartość True. Pozycja i w tej liście będzie oznaczała, czy liczba i jest liczbą pierwszą.
Ustawiamy liczby[0] i liczby[1] na False, ponieważ 0 i 1 nie są liczbami pierwszymi.

2. Iteracja przez liczby
Przechodzimy przez listę liczby zaczynając od liczby 2, czyli pierwszej liczby pierwszej.
Dla każdej liczby i, która ma wartość True w liście liczby, oznacza to, że i jest liczbą pierwszą. Następnie usuwamy (czyli ustawiamy na False) wszystkie wielokrotności tej liczby i zaczynając od i * i (ponieważ mniejsze wielokrotności i zostały już usunięte przez wcześniejsze liczby pierwsze).

3. Usuwanie wielokrotności
Jeśli i jest liczbą pierwszą, usuwamy wszystkie liczby w postaci i * i, i * (i + 1), i * (i + 2), ..., aż do n. Proces ten powtarzamy dla każdej liczby do pierwiastek(n)​, ponieważ każda liczba większa niż pierwiastek(n)​, która nie jest wielokrotnością żadnej liczby mniejszej lub równej pierwiastek(n) musi być liczbą pierwszą.

4. Zbieranie wyników
Po zakończeniu iteracji wszystkie liczby, które mają wartość True w liście liczby, są liczbami pierwszymi.

Przykład działania sita Eratostenesa

np. dla n=30

Tworzymy listę liczb od 0 do 30:
liczby = [False, False, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True]

Zaczynamy od i = 2
2 jest liczbą pierwszą, więc usuwamy wszystkie jej wielokrotności większe od 2, czyli 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30.

Lista po tej operacjiliczby = [False, False, True, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False]

Następnie i = 3
3 jest liczbą pierwszą, więc usuwamy wszystkie jego wielokrotności większe od 3, czyli 9, 12, 15, 18, 21, 24, 27, 30.Lista po tej operacji
liczby = [False, False, True, True, False, True, False, True, False, False, False, True, False, True, False, False, False, True, False, True, False, False, False, True, False, True, False, False, False, True, False]

Następnie i = 4
4 jest już oznaczone jako False (usunięte), więc przechodzimy dalej.

Następnie i = 5
5 jest liczbą pierwszą, więc usuwamy wszystkie jego wielokrotności większe od 5, czyli 25, 30.

Lista po tej operacjiliczby = [False, False, True, True, False, True, False, True, False, False, False, True, False, True, False, False, False, True, False, True, False, False, False, True, False, False, False, False, False, True, False]

Kontynuujemy ten proces do liczby nie większej niż pierwiastek z 30 (około 5,47), czyli w ww. przypadku do liczby 5 (co już zrealizowano), a następnie zbieramy wszystkie liczby oznaczone jako True.

Zatem wynik (liczby pierwsze do 30) to [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]

Złożoność obliczeniowa

Algorytm Sito Eratostenesa ma nietypową złożoność czasową O(n log⁡log⁡n) i złożoność pamięciową O(n), co czyni go bardzo efektywnym dla dużych wartości n.

Sito Eratostenesa w języku Python

dla n=30 (deklaracja na końcu kodu)

def sito_eratostenesa(n):
    # Tworzymy listę prawda/fałsz dla wszystkich liczb od 0 do n
    liczby = [True] * (n + 1)
    liczby[0] = liczby[1] = False  # 0 i 1 nie są liczbami pierwszymi
    # Rozpoczynamy sito
    for i in range(2, int(n**0.5) + 1):
        if liczby[i]:  # Jeśli liczba jest pierwsza
            # Usuwamy wszystkie jej wielokrotności
            for j in range(i * i, n + 1, i):
                liczby[j] = False
    # Zwracamy wszystkie liczby, które pozostały jako prawda (czyli liczby pierwsze)
    return [i for i in range(n + 1) if liczby[i]]
# Przykład użycia
print(sito_eratostenesa(30))

Sito Eratostenesa w języku C++

#include <iostream>
#include <vector>
std::vector<int> sito_eratostenesa(int n) {
    std::vector<bool> liczby(n + 1, true);
    liczby[0] = liczby[1] = false;
    for (int i = 2; i * i <= n; ++i) {
        if (liczby[i]) {
            for (int j = i * i; j <= n; j += i) {
                liczby[j] = false;
            }
        }
    }
    std::vector<int> primes;
    for (int i = 2; i <= n; ++i) {
        if (liczby[i]) {
            primes.push_back(i);
        }
    }
    return primes;
}
int main() {
    int n = 30;
    std::vector<int> primes = sito_eratostenesa(n);
    for (int prime : primes) {
        std::cout << prime << " ";
    }
    return 0;
}

Sito Eratostenesa w języku Java

import java.util.ArrayList;
import java.util.List;
public class SitoEratostenesa {
    public static List<Integer> sitoEratostenesa(int n) {
        boolean[] liczby = new boolean[n + 1];
        for (int i = 2; i <= n; i++) {
            liczby[i] = true;
        }
        for (int i = 2; i * i <= n; i++) {
            if (liczby[i]) {
                for (int j = i * i; j <= n; j += i) {
                    liczby[j] = false;
                }
            }
        }
        List<Integer> primes = new ArrayList<>();
        for (int i = 2; i <= n; i++) {
            if (liczby[i]) {
                primes.add(i);
            }
        }
        return primes;
    }
    public static void main(String[] args) {
        int n = 30;
        List<Integer> primes = sitoEratostenesa(n);
        System.out.println(primes);
    }
}

Sito Eratostenesa w języku JavaScript

function sitoEratostenesa(n) {
    let liczby = Array(n + 1).fill(true);
    liczby[0] = liczby[1] = false;
    for (let i = 2; i * i <= n; i++) {
        if (liczby[i]) {
            for (let j = i * i; j <= n; j += i) {
                liczby[j] = false;
            }
        }
    }
    let primes = [];
    for (let i = 2; i <= n; i++) {
        if (liczby[i]) {
            primes.push(i);
        }
    }
    return primes;
}
let n = 30;
console.log(sitoEratostenesa(n));

Sito Eratostenesa w języku PHP

<?php
function sitoEratostenesa($n) {
    $liczby = array_fill(0, $n + 1, true);
    $liczby[0] = $liczby[1] = false;
    for ($i = 2; $i * $i <= $n; $i++) {
        if ($liczby[$i]) {
            for ($j = $i * $i; $j <= $n; $j += $i) {
                $liczby[$j] = false;
            }
        }
    }
    $primes = [];
    for ($i = 2; $i <= $n; $i++) {
        if ($liczby[$i]) {
            $primes[] = $i;
        }
    }
    return $primes;
}
$n = 30;
$primes = sitoEratostenesa($n);
echo implode(", ", $primes);
?>

Komentarze