Algorithmique et Programmation : corrigé des exercices 1 à 12

Page 1
CAPES MATHS OPTION INFORMATIQUE
EXERCICES ALGORITHMIQUE ET PROGRAMMATION (PARTIE I)
Exercice 1 : Recherche dichotomique dans un tableau initialement trié
a. Ecrire en Python la fonction qui renvoie l’indice, de l’élément e passé en paramètre, dans un tableau trié.
Cette recherche se fera de façon dichotomique.
def rechercheDicho(tab,e) :
return rechercheDansBornes(tab,e,0,len(tab)-1)
def rechercheDansBornes(tab, e, idep, ifin) :
if ifin < idep : return -1
ind_milieu = (ifin + idep) // 2
if tab[ind_milieu] == e : return ind_milieu
if e < tab[ind_milieu] : return rechercheDansBornes(tab,e,idep,ind_milieu-1)
return rechercheDansBornes(tab,e,ind_milieu+1,ifin)
b. Quel est le coût d’une telle recherche ?
Au pire, on va trouver l’élément lorsque l’intervalle de recherche est de longueur 1, c'est-à-dire au bout de
d subdivisions, avec 2d = n. C'est-à-dire d=log2 (n). Ce qui nous donne un coût en .
Exercice 2 : Recherche dun mot dans une chaîne
a. Ecrire une fonction en Python qui prend en paramètres un mot et une chaîne de caractères et détermine si
le mot est dans la chaîne (sans utiliser la fonction in déjà existante en Python).
def appartient (mot, chaine) :
n, p = len(chaine), len(mot)
i = 0
while i <= n-p :
if chaine[i : i+p] == mot :
return True
i += 1
return False
b. Estimer la complexité de l’algorithme proposé dans le pire des cas.
Le pire des cas est celui on fait le plus grand nombre de passages dans la boucle while, et cela se
produit lorsuqe le mot n’est pas dans la chaîne. On commence par 3 affectations (n,p,i), puis à chaque
passage dans la boucle il y a p comparaisons de caractères (de i à i+p) et une incrémentation de i.
     

         
La compexité est en     .
Exercice 3 : Conversion décimal-binaire
L’objectif est de créer un programme qui code un nombre entier naturel, donné en écriture décimale, en binaire. Les
nombres binaires seront représentés par des chaînes de caractères. Pour plus de lisibilité, on insérera un espace
tous les quatres caractères en partant du dernier. Ansi, le nombre décimal 525 sera traduit par la chaîne "10 0000
1101" en binaire.
Page 2
a. Ecrire une fonction conversion en Python, qui prend en paramètre un nombre entier naturel en décimal et
renvoie la chaîne de caractères composée uniquement de 0 et de 1 correspondant à son écriture binaire.
On ne cherchera pas encore à insérer d’espaces.
def conversion (n) :
bin = str(n % 2) # premier reste dans la chaine resultat
q = n // 2 # premier quotient
while q != 0 : # tant que le quotient est non nul
n , q = q , q // 2 # maj n et q
bin = str (n % 2) + bin # ajout à gauche
return bin
b. Ecrire une fonction prenant en entrée une chaîne de caractères et réalisant l’insertion d’un espace tous les
quatres caractères en partant du dernier.
def insererEspace (ch) :
i = 0 # compteur
M = '' # chaine resultat
n = len(ch)
while i <= n-4 :
M = ' ' + ch[n-i-4:n-i] + M # insertion espace tous les 4 caractères
i += 4
M = ch[0:n-i] + M # ajout des caractères restants (de gauche)
return M
c. Modifier la fonction conversion pour prendre en compte l’insertion des espaces.
def conversion (n) :
bin = str(n % 2)
q = n // 2
while q != 0 :
n , q = q , q // 2
bin = str (n % 2) + bin
return insererEspace(bin)
Exercice 4 : Crible dEratosthène et décomposition en facteurs premiers
a. On se propose de calculer tous les nombres premiers plus petits qu’un entier donné. La méthode consiste
à calculer pas à pas ces nombres en utilisant la règle suivante : si un entier n’est divisible par aucun
nombre premier plus petit que alors il est lui-même premier. Quelles sont les structures de données
qu’on peut utiliser pour résoudre ce problème ? Quelle est la plus efficace ?
Il y a plusieurs possibilités :
- On réserve un tableau statique de taille .
- On utilise une liste.
Voici un tableau représentant différentes valeurs de , le cardinal  des nombres premiers plus petits
que et le ratio  :

ratio
10
4
40%
102
25
25%
103
168
16,8%
104
1229
12,29%
105
9592
9,59%
106
78498
7,84%
107
664579
6,64%
Page 3
108
5761455
5,76%
109
50847534
5,08%
On gaspillerait donc beaucoup de mémoire en utilisant un tableau de taille fixe égale à . Mieux vaut
utiliser une structure de données extensible automatiquement en fonction des besoins : elle s'agrandira
automatiquement au fur et à mesure que l'on calculera les nombres premiers.
b. Ecrire en Python la procédure eratosthene qui retourne le tableau des nombres premiers plus petits que
passé en paramètre.
def eratosthene(n):
# Préconditions : n > 1
# Résultat : le tableau contenant les nombres premiers <= n
t = [2]
for i in range(3,n+1) :
k = 0
divisible = False
while k < len(t) and not divisible :
if i % t[k] == 0 :
divisible = True
else :
k = k + 1
if (not divisible) :
t.append(i)
return t
c. Ecrive en Python la fonction decompose, qui retourne la décomposition d’un entier par le produit de
nombres premiers.
On se propose d’écrire la décomposition de sous la forme     avec  
et premier.
- temp est une liste qui contient tous les nombres premiers plus petits que (crible)
- A chaque fois qu’un nombre premier divise , le facteur associé est multiplié par et est divisé par
.
- La variable diviseur est à vraie tant que le nombre premier en cours divise .
def decompose (n) :
# Préconditions : n > 1
# Resultat : le tableau contenant les nombres premiers décomposant n
i = 0
diviseur = False
temp = eratosthene(n)
tab = [1]
j = 0 # j represente len 1
while i < len(temp) and n != 1 :
if n % temp[i] == 0 :
# le facteur est multiplié par le diviseur en cours
tab[j] = tab[j] * temp[i]
n = n // temp[i]
diviseur = True
else :
i = i + 1 # on passe au nombre premier suivant dans temp
if diviseur :
tab.append(1) # on initialise le jieme facteur à 1
j = j + 1 # Rappel, j ne sert qu’à simplifier l’écriture
diviseur = False
return tab
Page 4
Exercice 5 : Tri mystère
Voici le début de la trace d’un algorithme de tri :
10
56
-2
52
-8
41
13
-8
56
-2
52
10
41
13
-8
-2
56
52
10
41
13
-8
-2
10
52
56
41
13
a. De quel algorithme s’agit-il ? Pourquoi ?
On sélectionne le plus petit élément du tableau pour l’échanger avec le premier, puis le plus grand élément
du sous-tableau [2..7] pour l’échanger avec le second élément. Il s’agit donc d’un tri par sélection.
a. Complétez le tableau ci-dessus en indiquant les étapes suivantes, jusqu’à ce que le tableau soit
complètement trié.
-8
-2
10
13
56
41
52
-8
-2
10
13
41
56
52
-8
-2
10
13
41
52
56
b. Si le tableau est de taille n, quelle est la complexité de cet algorithme en fonction de n ? Justifiez
(brièvement) votre réponse.
Pour chaque élément i allant de 2 à n, l’algorithme de tri par sélection effectue 3 affectations d’Elements
(permutation de deux valeurs via une variable temporaire), et (n i) comparaisons d’Elements.
On a donc
    affectations et   
    comparaisons d’Elements.
Le coût total est donc de la forme 3c1(n - 1) + c2n(n - 1)/2, donc l’algorithme est O(n2).
Rappel : toutes les formules des sommes peuvent se déduire de
   
Exercice 6 : Analyse de la complexité dun algorithme
On considère le pseudo-code suivant, comportant deux « tant que » imbriqués. On cherche à mesurer la complexité
de cette imbrication en fonction de n. Pour cela, on utilise la variable « compteur », qui est incrémentée à chaque
passage dans le « tant que » interne.
Variables :
n : entier
compteur : entier
i, j : entiers
Début
Afficher(« Quelle est la valeur de n ? »)
Saisir(n)
compteur 0
i 1
Tant que (i < n) Faire
j i + 1
Tant que (j n) Faire
compteur compteur + 1
Page 5
j j + 1
Fin tantque
i i * 2
Fin tantque
Afficher(compteur)
Fin
a. Quelle est la valeur finale du compteur dans le cas où n = 16 ?
Pour i=1, j varie de 2 à 16 inclus, on fait donc 15 incrémentations du compteur.
Pour i=2, j varie de 3 à 16 inclus, on fait donc 14 incrémentations du compteur.
Pour i=4, j varie de 5 à 16 inclus, on fait donc 12 incrémentations du compteur.
Pour i=8, j varie de 9 à 16 inclus, on fait donc 8 incrémentations du compteur.
Ensuite, i vaut 16, donc on sort du « Tant que (i < n) ».
Au total, on a donc fait 15+14+12+8 = 49 incrémentations du compteur. Donc compteur vaut 49 en sortie
du programme.
b. Considérons le cas particulier n est une puissance de 2 : on suppose que    avec p connu. Quelle
est la valeur finale du compteur en fonction de p ? Justifiez votre réponse.
i prend successivement les valeurs suivantes : 20, 21, 22, ... 2p-1, soit 2k avec k variant de 0 à (p-1). Pour
chacune de ces valeurs, on fait (n-i) incrémentations, soit (2p - 2k) incrémentations. Ensuite i vaut 2p, ce qui
provoque la sortie du « Tant que (i < n) ». On ne fait pas d’incrémentations du compteur pour cette
dernière valeur de i.
  

  

       
Rappel :        


Ainsi, la valeur finale du compteur est    .
c. Réexprimez le résultat précédent en fonction de n.
     . (rappel :      )
On a donc une complexité en .
Exercice 7 : Tri à bulles
Le tri à bulles est un algorithme de tri qui s’appuie sur des permutations répétées d’éléments contigus qui ne sont
pas dans le bon ordre.
Procédure tri_bulles(tab : tableau [1..n] de réels)
Précondition : tab est un tableau contenant n réels
Postcondition : les éléments de tab sont triés dans l’ordre croissant
Variables locales : i, j : entiers, e : réel
Début
1 i 1
2 Tant que (i <= n-1) Faire
3 j n
4 Tant que (j >= i+1) Faire
5 Si tab[j] < tab[j-1] Alors
6 {on permute les deux éléments}
7 e tab[j-1]
1 / 14 100%

Algorithmique et Programmation : corrigé des exercices 1 à 12

La catégorie de ce document est-elle correcte?
Merci pour votre participation!

Faire une suggestion

Avez-vous trouvé des erreurs dans linterface ou les textes ? Ou savez-vous comment améliorer linterface utilisateur de StudyLib ? Nhésitez pas à envoyer vos suggestions. Cest très important pour nous !