Probleme – Le crible d'Ératosthène, et ce qu'il coûte
Exercice · niveau 3 (difficile) · informatique (MP2I/MPI), chapitre 1 — Le langage C
É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 </em> 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.
Les autres exercices de ce chapitre Le cours du chapitre
Un blocage sur cet exercice ? Le tuteur d'Adloun guide par questions, sans donner la réponse.