Adloun

informatique (MP2I/MPI) · Chapitre 1 · Application directe du cours

Problème — Le crible d'Ératosthène, et ce qu'il coûte

Le langage C · niveau 3 (difficile)

Énoncé

  • Écrire une fonction qui rend un tableau de booléens marquant les nombres premiers jusqu'à .
  • Justifier que la boucle extérieure peut s'arrêter à .
  • Justifier que la boucle intérieure peut commencer à .
  • Que vaut la complexité ?

Corrigé

1. Le crible.


/* Renvoie un tableau c de n+1 booléens : c[k] vaut true ssi k est premier.
   L'appelant devra faire free. Précondition : n >= 1. */
bool* crible(int n) {
    assert(n >= 1);
    bool* c = malloc((size_t) (n + 1) * sizeof(bool));
    if (c == NULL) { return NULL; }
    c[0] = false;
    if (n >= 1) { c[1] = false; }
    for (int k = 2; k <= n; k = k + 1) { c[k] = true; }
    for (int p = 2; p * p <= n; p = p + 1) {
        if (c[p]) {
            for (int m = p * p; m <= n; m = m + p) { c[m] = false; }
        }
    }
    return c;
}

2. L'arrêt à . Si est composé, il s'écrit avec . Alors , donc . Tout composé possède donc un diviseur premier , et il aura été rayé lors du passage sur ce diviseur. Les n'ont plus rien à rayer.

3. Le départ à . Un multiple avec possède un facteur dont le plus petit diviseur premier est : il a donc déjà été rayé lors d'un passage antérieur. Commencer à ne perd rien et évite de rayer plusieurs fois.

4. La complexité. Pour chaque premier , la boucle intérieure fait environ tours. Le total est

en admettant le résultat classique . En espace, le crible occupe octets.

Mise en garde sur p * p <= n. Le produit est calculé en int. Pour proche de la capacité maximale, approche et approche : cela tient. Mais la variante p <= sqrt(n) serait pire — elle appellerait une fonction flottante à chaque tour, avec les problèmes de précision du chapitre chap:algo-prog. On garde la forme entière.

Exercices semblables

Le cours du chapitre · Tous les exercices du chapitre