Exercices Corrigés de Prof. Habiba Drias
Exercices Corrigés de Prof. Habiba Drias
Exercices Corrigés de Prof. Habiba Drias
E xercice 1.1
Ecrire six algorithmes différents pour déterminer si un nombre entier est premier ou
composé. Evaluer la complexité pour chacun des algorithmes proposés.
E xercice 1.2
&RQVLGpUHU DOJRULWKPHV $ $ « $ FRQoXV SRXU UpVRXGUH XQ même problème de
taille n. La complexité en temps de chacun de ces algorithmes est exprimée dans la table
ci-dessous.
E xercice 1.4
&RQVLGpUHUO¶DOSKDEHW^`XQSDOLQGURPHHVWXQPRWTXLVHSUpVHQWHVRXVOHIRUPDWZZ-1
2ZHVWXQPRWTXHOFRQTXHGHO¶DOSKDEHWHWZ-1 HVWO¶LPDJHPLURLUGHZ
1) Ecrire un algorithme qui reconnaît des palindromes et calculer sa complexité
2) Ecrire un programme assembleur pour reconnaitre des palindromes et calculer sa
complexité
3) Concevoir une machine de Turing pour reconnaître les palindromes. Le résultat doit
être égal à 1 si le mot en entrée est un palindrome, 0 sinon. Calculer sa complexité
E xercice 1.5
&RQVLGpUHUO¶DOSKDEHW^`HWOHODQJDJH/ ^ QEGH QEGH`
1) Ecrire un algorithme qui reconnaît L, calculer sa complexité
2) Ecrire un programme assembleur, calculer sa complexité
3) Concevoir une machine de Turing pour reconnaître les mots de L. Le résultat doit
être égal à 1 si le mot en entrée est correct, 0 sinon. Calculer sa complexité
E xercice 1.6
1) Concevoir une machine de Turing pour additionner 2 nombres binaires. Calculer sa
complexité
2) Ecrire un algorithme correspondant à la machine de Turing de la première question.
Calculer sa complexité
3) Ecrire un programme assembleur pour additionner 2 nombres binaires et calculer sa
complexité
E xercice 1.7
&RQVLGpUHUXQWDEOHDXFRQVWLWXpGHVQSUHPLHUVQRPEUHVHQWLHUV «Q 8QHPpWKRGHGH
détermination des nombres premiers inférieurs au sens large à n, consiste à considérer le
nombre 2 qui est premier puis à éliminer tous les nombres multiples de 2 car ils ne sont pas
premiers, ensuite itérer ce processus en continuant avec le nombre suivant non éliminé c'est-à-
GLUHMXVTX¶jWUDLWHUWRXVOHVHQWLHUVGXWDEOHDX
1) Illustrer chaque itération du procédé de calcul des nombres premiers décrit ci-dessus
sur les 10 premiers nombres entiers
2) (FULUH XQ DOJRULWKPH GH FDOFXO HW G¶LPSUHVVLRQ GHV QRPEUHV SUHPLHUV LQIpULHXUV DX
VHQVODUJHjQ,OHVWUHFRPPDQGpSDUVRXFLGHVLPSOLILFDWLRQGHO¶DOJRULWKPHGHPHWWUH
OHQRPEUHjV¶LOHVWSUHPLHUHWjVLQRQXQHIRLVTX¶LOHVWWUDLWp
3) &DOFXOHUODFRPSOH[LWpGHO¶DOJRULWKPH
4) (FULUHO¶DOJRULWKPHHQDVVHPEOHXUjO¶DLGHGXMHXG¶LQVWUXFWLRQVGRQQpHQFRXUV
Habiba Drias
Exercice1.1
L’algorithme le plus simple que nous dénotons A1 découle directement de la définition
d’un nombre premier. Rappelons qu’un nombre premier n est un nombre entier qui n’est
divisible que par 1 et par lui-même. L’algorithme va donc consister en une boucle dans
laquelle on va tester si le nombre n est divisible par 2, 3, …, n-1.
Algorithme A1 ;
début
premier = vrai ;
i=2;
tant que (i <= n-1) et premier faire
si (n mod i = 0) alors premier = faux sinon i = i+1 ;
fin.
Le pire cas qui nécessite le plus long temps, correspond au cas où n est premier car c’est
dans ce cas que la boucle s’exécute avec un nombre maximum d’itérations. Dans ce cas ce
nombre est égal à n-2. La complexité est donc en O(n).
Nous savons que pour améliorer l’algorithme, il est judicieux d’arrêter la boucle à n/2 car
si n est divisible par 2, il est aussi divisible par n/2 et s’il est divisible par 3, il est aussi
divisible par n/3. De manière générale, si n est divisible par i pour i = 1 … [n/2] où [n/2]
dénote la partie entière de n/2, il est aussi divisible par n/i. Il n’est donc pas nécessaire de
vérifier qu’il est divisible par un nombre supérieur à n/2. Le deuxième algorithme est
donc :
Algorithme A2 ;
début
premier = vrai ;
i=2;
tant que (i <= [n/2]) et premier faire
si (n mod i = 0) alors premier = faux sinon i = i+1 ;
fin.
Le cas le plus défavorable qui nécessite le plus long temps correspond toujours au cas où n
est premier et dans ce cas le nombre d’itérations est égal à n/2 -1. La complexité est donc
en O(n)
Une autre amélioration possible consiste à tester si n est impair et dans ce cas dans la
boucle, il ne faut tester la divisibilité de n que par les nombres impairs. L’algorithme A3
est donc comme suit :
Algorithme A3 ;
début
premier = vrai ;
si (n <> 2) et (n mod 2 = 0) alors premier = faux
sinon si ( n <> 2) alors
début
i=3 ;
tant que (i <= n-2) et premier faire
si (n mod i = 0) alors premier = faux sinon i = i+2 ;
fin
fin.
Le pire cas correspond au cas où n est premier et dans ce cas le nombre maximum
d’itérations de la boucle est égal à [n/2] -2, la complexité est en O(n).
Le nombre d’itérations de la boucle pour un nombre premier est égal à la moitié du nombre
d’itérations de A3, il est égal à [n/4] – 1. La complexité est donc en O(n).
Une bonne amélioration de l’algorithme serait d’arrêter la boucle non pas à [n/2] mais à 𝑛
car en effet si n est divisible par x, il est aussi divisible par n/x et donc il serait judicieux de
Algorithme A6 ;
début
premier = vrai ;
si (n <> 2) et (n mod 2 = 0) alors premier = faux
sinon si ( n <> 2) alors
début
i=3 ;
tant que (i <= [ 𝑛)]) et premier faire
si (n mod i = 0) alors premier = faux sinon i = i+2 ;
fin
fin.
Le nombre maximum d’itérations de la boucle est égal à ([ 𝑛)]/2 – 1). La complexité est
donc en O( 𝑛).
Récapitulatif
Exercice1.2
2) Le temps nécessaire au traitement des tailles du problème : n=10, n=100 et n=1000 pour
une unité de temps égale à une milliseconde est montré dans le tableau suivant :
Exercice 1.3
1) La fonction suivante calcule le pgcd selon la formule donnée :
fonction pgcd(a,b : entier) : entier ;
var
x,y,q,r : entier;
début
x := a;
y :=b;
q := x / y;
r := x – q*y;
tant que (r <> 0) faire
début
x := y;
y := r;
q := x / y;
r := x – q*y ;
fin;
pgcd := y;
fin;
2) Complexité
Le pire cas correspond à la situation où à chaque itération, le quotient de la division de x
par y est égal à 1 et donc au nombre maximum d’itérations. Dans ce cas le reste de la
division est égal à la différence entre x et y puisque :
r := x – q*y = x – 1*y = x-y
Si x est supérieur à y, la séquence r, y et x fait partie de la suite de Fibonnacci, car les
deux dernières itérations correspondent respectivement à r=1 et à r=0, qui coïncident avec
l’initialisation de la suite de Fibonnacci. En résumé le cas le plus défavorable correspond
au calcul du pgcd de deux nombres consécutifs de la suite de Fibonnacci Fn-1 et Fn-2 où
Fn = Fn-1 + Fn-2, F1 = 1 et F0 = 0.
Fn > 2*Fn-2 > 2*2*Fn-4 > …> 2k
Où k est égal approximativement à la moitié de la longueur de la suite de Fibonnacci qui
correspond au nombre d’itérations de la boucle. Le nombre d’itérations m est égal donc à
2k. Si a est supérieur à b, a=Fn et par conséquent :
a > 2k
ln a > ln2k = k ln2
k < (1/ln2) ln a
d’où : m < (2/ln2) ln a, La complexité est donc en O(ln a).
3) Version récursive
fonction pgcd(a,b : entier) : entier ;
var
q,r : entier ;
début
si (b = 0) alors pgcd := a sinon début q := a div b; {division entière }
r := a – q*b;
pgcd := pgcd(b,r);
fin;
fin;
La complexité de la fonction pgcd est la même que celle calculée pour la 2ème question.
Exercice 1.4
1) Algorithme :
var i,j,c : entier ;
T[1..max] : tableau d’entiers;
début
i:=1,
j:= max ;
tant que (T[i]=T[j]) et (i<j) faire
début i:= i+1;
j := j-1;
fin;
si (i>j) alors écrire(‘mot correct’) sinon écrire (‘mot incorrect’);
fin;
3) Machine de Turing :
Première solution : Machine à un seul ruban :
On suppose que le mot se trouve initialement sur le premier ruban. Nous aurons besoin de
définir 8 états avec les rôles suivants :
- q0 : état initial, met à blanc le 1er bit rencontré et transite vers q1 si le bit est égal à
1, à q2 s’il est égal à 0
- q1 : sert à comparer le 1er 1 de la chaine avec le dernier 1
- q2 : sert à comparer le 1er 0 de la chaine avec le dernier 0
- q3 : sert à mettre à blanc le dernier 1 de la chaine
- q4 : sert à mettre à blanc le dernier 0 de la chaine
- q5 : sert à se déplacer vers la gauche et positionner la tête de lecture vers le 1er bit
de la chaine restante
- q6 signale un succès
- q7 signale un échec
La taille du problème est celle du palindrome et est égale à n. Le pire cas correspond au
cas où la donnée est un palindrome car c’est dans ce cas que la machine fait le maximum
de transitions. Le nombre de transitions effectuées pour reconnaitre un palindrome est de :
2(n+1)+2n+2(n-1)+ …+2 = 𝑛+1 1 2𝑖 = 2 𝑛+11 𝑖 = 2(n+1)(n+2)/2= (n2+3n+2).
La complexité temporelle est donc en O(n2) et la complexité spatiale est en O(n).
Exercice 1.5
1) programme L ;
var
ecart, c : entier ;
début
lire(c);
écart := 0;
tant que (c=0) ou (c=1) faire
début
si (c=0) alors écart := écart + 1
sinon si (c=1) alors écart := écart – 1 ;
fin;
si (écart = 0) alors écrire (‘mot correct’) sinon écrire (‘mot incorrect’)
fin.
Le nombre d’instructions exécutées pour reconnaitre un mot du langage est égal à 2+ 3n+1.
La complexité de l’algorithme est donc en O(n).
0 1 2 3 4 5 6 7 8 9 10
1 0 0 3 1 5 1 7 1 9 1
2 0 0 0 1 5 1 7 1 1 1
3 0 0 0 1 1 1 7 1 1 1
4 0 0 0 1 1 1 1 1 1 1
var i, j, r: entier ;
début
pour i := 2 à n faire
début
si T[i] <> 1 alors début
T[i] := 0;
écrire (i);
fin;
pour j := i+1 à n faire
si (T[j] mod i = 0) alors T[j] :=1;
fin;
fin;
3) Il existe deux boucles dans l’algorithme. La boucle externe s’exécute de 2 à n donc (n-
1) fois. La boucle interne par contre s’exécute un nombre de fois qui dépend de i qui
𝑛−2 (𝑛−1)
varie de n-2 à 1. La complexité est donc de : 𝑛−2
1 𝑖= . Elle est en O(𝑛2 ).
2
4) Le programme assembleur :
MOV #10, R4
MOV #2, R0
L5: SUB R4, R0
JZ R0, Fin
ADD R4, R0
SUB #1, T[R0]
JZ T[R0], L0
MOV #0, T[R0]
OUTPUT R0
L0: MOV R0, R1
L3: ADD #1, R1
MOV T[R1], R2
MOV T[R1], R3
DIV R0, R2
IDIV R0, R3
SUB R2, R3
JZ R3, L1
JMP L2
L1: MOV #0, T[R1]
L2: SUB R4, R1
JZ R1, L4
ADD R4, R1
JMP L3
L4: ADD #1, R0
JMP L5
Fin : STOP
T: 0
1
2
3
4
5
6
7
8
9
10