Documentos de Académico
Documentos de Profesional
Documentos de Cultura
CHAPITRE 1
LES ENREGISTREMENTS
I/ Définition :
Un enregistrement est un type de données défini par l'utilisateur et qui permet de
grouper un nombre fini d'éléments (ou champs) de types éventuellement différents.
II/ Déclaration :
Déclaration d’une structure enregistrement
En algorithmique :
Puisque l'enregistrement est un nouveau type, on commence par sa déclaration :
En Pascal :
VAR
identificateur_objet : Nom_type ;
III/ Utilisation
4INFINFRC0001 Page 1
http://www.najah.com
En algorithmique En Pascal
variable.champ ← valeur variable.champ := valeur ;
Exemple :
En algorithmique :
élève.nom ← "Swidi"
élève.prénom ← "Basma"
élève.sexe ← "F"
élève.numéro ← 18
élève.moyenne ← 13.25
élève.num_cin ← 12345678
En Pascal :
Le type enregistrement.
4INFINFRC0001 Page 2
http://www.najah.com
numero : Byte ;
moyenne : Real ;
num_cin : LongInt ;
End ;
VAR
eleve : Fiche ;
eleve.nom := 'Swidi' ;
eleve.prenom := 'Basma' ;
eleve.sexe := 'F' ;
eleve.numero := 18 ;
eleve.moyenne := 13.25 ;
eleve.num_cin := 12345678 ;
Exemple :
Au niveau de l'analyse :
élève.nom = Donnée ("Entrer le nom de l'élève : ")
Au niveau de l'algorithme :
Ecrire ("Entrer le nom de l'élève : ") ; Lire (élève.nom)
Au niveau du Pascal :
Write ('Entrer le nom de l''élève : ') ; ReadLn (eleve.nom) ;
Exemple :
4INFINFRC0001 Page 3
http://www.najah.com
Au niveau du Pascal :
WriteLn ('Nom : ', eleve.nom) ;
Syntaxe :
Au niveau de l'analyse et de l'algorithme Au niveau du Pascal
Avec variable Faire With variable Do
{ensemble d'actions} Begin
Fin Avec {ensemble d'actions}
End;
Au Niveau de l'algorithme :
{Lecture}
Ecrire ("Entrer le sexe de l'étudiant : ") ; Lire (sexe)
{Ecriture}
Ecrire ("Moyenne : ", moyenne)
Fin Avec
Au Niveau du Pascal :
With etudiant Do
Begin
nom := 'Swidi' ;
4INFINFRC0001 Page 4
http://www.najah.com
Vecteur d'enregistrements
Un tableau ne peut grouper ou contenir que des éléments de même type, et puisque les
éléments d'un enregistrement sont de même type qui est celui de l'enregistrement, donc on
peut utiliser un tableau ou un vecteur d'enregistrements.
Exemple :
Type
Fiches = Enregistrement
nom, prénom : Chaîne
sexe : Caractère
numéro : Entier non signé
moyenne : Réel
num_cin : Entier long
Fin Fiches
Tab = Tableau de 30 Fiches {tableau d'enregistrements fiches}
Tableau de déclaration des objets :
Activité
Un médecin enregistre sur ordinateur les fiches de ses Patients. Une fiche a la la structure
suivante :
- un nom (chaîne de 30 caractères maximum)
- un numéro (entier)
- un numéro de téléphone (10 caractères maximum)
- un code d'assurance (entier non signé).
1/ Ecrire les analyses, les algorithmes des différents modules d'un programme nommé Fiche,
qui permet la saisie et l'affichage de l'enregistrement d'un Patient.
2/ Traduire ce programme en Pascal
1/ Analyses et algorithmes :
4INFINFRC0001 Page 5
http://www.najah.com
Type
Personne = Enregistrement
nom : Chaîne de 30 caractères
numéro : Entier
tel : Chaîne de 10 caractères
code : Entier non signé
Fin Personne
4INFINFRC0001 Page 6
http://www.najah.com
Fin Avec
2) Fin Saisir
2/ Traduction en Pascal
PROGRAM Fiche ;
USES Crt ;
TYPE Personne = Record
nom : String [30] ;
numero : Integer ;
tel : String [10] ;
code : Word ;
End ;
VAR Patient : Personne ;
{--------------------------------------------------------------------------------------------}
PROCEDURE Saisir (VAR Patient : Personne) ;
BEGIN
With Patient Do
Begin
Write ('Entrer le nom de la personne : ') ; ReadLn (nom) ;
Write ('Entrer son numéro : ') ; ReadLn (numero) ;
Write ('Entrer son numéro de téléphone : ') ; ReadLn (tel) ;
Write ('Entrer son code d’’assurance : ') ; ReadLn (code) ;
End ;
END ;
{--------------------------------------------------------------------------------------------}
PROCEDURE Afficher (Patient : Personne) ;
BEGIN
With Patient Do
4INFINFRC0001 Page 7
http://www.najah.com
Begin
WriteLn ('Nom : ', nom) ;
WriteLn ('Numéro : ', numero) ;
WriteLn ('Numéro du téléphone : ', tel) ;
WriteLn ('Code d’’assurence : ', code) ;
End;
END;
{= = = = = = = = = = = Programme Principal = = = = = = = = = = =}
BEGIN
Saisir (Patient) ;
Afficher (Patient);
END.
4INFINFRC0001 Page 8
http://www.najah.com
CHAPITRE 2
LA RECURSIVITE
I- Introduction
Activité 1
Reprenons l'exercice de calcul de la factorielle étudié en troisième année. Nous avons écrit la
fonction suivante :
NB : Ce calcul a été obtenu à partir d'une boucle Pour … Faire. C'est un traitement itératif.
4INFINFRC0002 Page 1
http://www.najah.com
On remarque que l'écriture en rouge représente la factorielle de n-1, donc on peut écrire :
Factorielle (n) = n * factorielle (n-1)
et factorielle (0) = 1
Ce nouveau calcul n'utilise pas un procédé itératif mais il appelle la même fonction avec un
nouveau paramètre qui est (n-1).
On peut donc écrire une fonction récursive de calcul de la factorielle d'un entier N.
{----------------------------------------------------------------}
Function Factorielle (n : Integer) : LongInt;
Begin
If (n = 0) Then Factorielle := 1
Else Factorielle := n * Factorielle (n - 1);
End;
{= = = = = = = Programme Principal = = = = = = = = }
BEGIN
Write ('n = '); ReadLn (n);
Write ('n! = ', Factorielle (n));
END.
Activité 2
4INFINFRC0002 Page 2
http://www.najah.com
- Ecrire une analyse et l'algorithme d'une Procédure qui saisie un entier N tel que (2 ≤ N ≤
100).
Nous avons vu qu'une fonction peut être récursive. Une procédure peut-elle être l'être ?
Si oui, proposer une version récursive de cette procédure saisie.
Analyse
Résultat = Lire et n'accepter qu'une valeur de N entre 2 et 100.
Traitement :
Répéter la lecture de N jusqu'à une saisie valide suivant la condition proposée.
Fin Analyse
Algorithme :
0) Procédure Saisie (VAR N : Entier)
1) Ecrire ("Entrer un entier N : ")
2) Lire (N)
3) Si (N < 2) OU (N > 100) Alors Saisie (N) {appel récursif}
4) Fin Saisie
II- Définitions
La récursivité est une méthode algorithmique qui consiste à appeler un sous-programme dans
son propre corps.
Un sous-programme récursif est un module qui fait appelle à lui-même. A chaque appel, il y a
mémorisation d’une valeur différente d'un même paramètre formel.
4INFINFRC0002 Page 3
http://www.najah.com
Application 1
On se propose de calculer et d’afficher la valeur de x à la puissance n.
x et n sont respectivement un réel et un entier donnés.
Questions :
a) Analyser le problème en utilisant un module récursif,
b) Donner les algorithmes correspondants,
c) Traduire l'ensemble en un programme Pascal.
a) Analyse du problème
Résultat : Ecrire (x, " à la puissance ", n, " = ", Fn Puissance (x, n))
Traitement :
Puissance est une fonction récursive permettant de calculer la valeur de xn.
Fin Analyse
4INFINFRC0002 Page 4
http://www.najah.com
Programme Pascal
PROGRAM Prg_Puissance ;
USES WinCrt ;
VAR
x : Real ;
n : Integer ;
{------------------------------------------------------------------------------------}
Function Puissance (x : Real; n : Integer) : Real;
Begin
If (n = 0) Then Puissance := 1
Else If (n < 0) Then Puissance := 1 / Puissance (a, -n)
Else Puissance := a * Puissance (a, n - 1);
END;
{========================== p p ==============================}
BEGIN
Write ('Donner un réel ');
ReadLn (x);
Write ('Donner un entier : ');
ReadLn (n);
4INFINFRC0002 Page 5
http://www.najah.com
WriteLn (' x, " à la puissance ", n, " = ", Puissance (x, n)) ;
END.
Application 2
Ecrire un module récursif, qui cherche la présence d’une valeur entière V dans un tableau T
de n d'entiers (4 ≤ n ≤ 20), en utilisant la méthode de recherche dichotomique.
NB : Le tableau sera trié au cours de son remplissage.
Questions :
a) Analyser le problème et écrire son algorithme
b) Proposer une analyse et un algorithme du module récursif,
a) Analyse du problème
Résultat : Si existe Alors Ecrire (V, " existe dans le tableau T.")
Sinon Ecrire (V, " n’existe pas dans le tableau T.")
Traitement :
existe est le résultat Booléen d'une fonction de recherche par la technique de dichotomie, elle
est appelée Dicho_Rec (Dichotomie récursive)
Fin Analyse
0) Début Recherche
1) Saisir (n)
2) Remplir_Trier (n, T)
3) Ecrire ("Donner un entier : ") , Lire (V)
4) existe Å Dicho_Rec (1, n, V, T)
5) Si existe Alors Ecrire (V, " existe dans le tableau T.")
Sinon Ecrire (V, " n’existe pas dans le tableau T.")
Fin si
5) Fin Recherche
4INFINFRC0002 Page 6
http://www.najah.com
4INFINFRC0002 Page 7
http://www.najah.com
Sinon Si V< T[milieu] et début < milieu, alors nous cherchons l’existence de V dans la
première moitié du tableau (Dich_Rec ← Fn Dich_Rec (debut, milieu-1, V, T))
Sinon Si V > T[milieu] et Fin > milieu, alors nous on cherche V dans l'autre moitié du tableau
(Dicho_Rec ← Fn Dicho_Rec (milieu+1, fin, V, T))
milieu est le milieu d'un tableau entre début (case de départ) et Fin (case finale)
milieu ← (début + fin) Div 2
Fin Analyse
2) Fin Saisie
Traduction en Pascal
PROGRAM Recherche ;
USES WinCrt ;
TYPE TAB = ARRAY[1..20] Of Integer ;
VAR
T: TAB ;
n, V : Integer ;
existe : Boolean ;
{-----------------------------------------------------------------------------------------}
PROCEDURE Saisie (VAR n : Integer);
BEGIN
Repeat
Write ('N = ');
ReadLn (n);
Until n IN [4..20];
END ;
4INFINFRC0002 Page 9
http://www.najah.com
{-----------------------------------------------------------------------------------------}
PROCEDURE Remplir_Trier (n : Integer ; VAR T : TAB) ;
VAR i : Integer ;
BEGIN
Write ('T[1] = ') ;
ReadLn (T[1]) ;
For i:= 2 To N Do
Begin
Repeat
Write ('T[', i, '] = ') ;
ReadLn (T[i]) ;
Until (T[i] >= T[i-1]) ;
End;
END;
{-----------------------------------------------------------------------------------------}
FUNCTION Dicho_Rec (debut, fin, V : Integer ; T : Tab) : Boolean ;
VAR milieu : Integer ;
BEGIN
milieu := (debut + fin) DIV 2 ;
If (V = T[milieu]) Then Dicho_Rec := True
Else If (V < T[milieu] ) AND (debut < milieu)
Then Dicho_Rec := Dicho_Rec (debut, milieu-1, V, T)
Else If (V > T[milieu] ) And (fin > milieu)
Then Dicho_Rec := Dicho_Rec (milieu +1, fin, V, T)
Else Dicho_Rec := False
END ;
{================= P P ===================================}
BEGIN
Saisie (n) ;
Remplir_Trier (n, T) ;
Write ('Donner un entier : ') ; ReadLn (V) ;
existe := Dicho_Rec (1, n, V, T) ;
If existe Then WriteLn (V, ' existe dans le tableau T.')
Else WriteLn (V, ' n''existe pas dans le tableau T.') ;
END.
4INFINFRC0002 Page 10
http://www.najah.com
CHAPITRE 3
- Les tris externes : Méthodes destinées à de grandes masses de données, stockées dans des
structures de données comme par exemple les fichiers.
*-*-*-*-*-*-*-*-*-*-*
Algorithme
0) Début Tri_Sélection
1) Proc Saisie (N)
2) Proc Remplir_Hasard (T, N)
3) Ecrire ("Tableau non trié ")
4) Proc Affiche_Tab (T, N)
4INFINFRC0003 Page 1
http://www.najah.com
Algorithme
0) Procédure Saisie (VAR N : Entier)
1) Répéter
Ecrire ("Entrer la taille du tableau : ")
Lire (N)
Jusqu'à (4 ≤ N ≤ 25)
2) Fin Saisie
4INFINFRC0003 Page 2
http://www.najah.com
Pour i de 1 à N Faire
T[i] Å Hasard * 100
Fin Pour
En Pascal, pour que cette fonction génère à chaque appel des nombres différents, elle doit être
initialisée avec la procédure prédéfinie Randomize.
Fin Analyse
Algorithme
0) Procédure Remplir_Hasard (VAR T : Vect ; N : Entier )
1) Randomize
2) Pour i de 1 à N Faire
T[i] Å Hasard * 100
Fin Pour
3) Fin Remplir_Hasard
Lorsque le tri est par ordre décroissant, la méthode appelée tri par recherche de maxima, car
on commence par le plus grand.
Dans notre cas c'est un tri décroissant, donc c'est une sélection par par recherche de minima.
- La recherche de la position de la plus petite valeur à partir d'un point de départ donné est
confiée à une fonction nommé Cherche_Min.
- La permutation du contenu de deux cases du tableau est faite par une procédure nommé
Permute.
Fin Analyse
4INFINFRC0003 Page 3
http://www.najah.com
Algorithme
0) Procédure Tri_Select (VAR T : Vect ; N : Entier )
1) Pour i de 1 à N-1 Faire
Pos_Min Å Fn Cherche_Min (T, i, N)
Si Pos_Min ≠ i Alors Proc Permute (T[i] , T[Pos_Min])
Fin Si
Fin Pour
2) Fin tri_Select
Algorithme
0) Fonction Cherche_Min (T : Vect ; départ, N : Entier ) : Entier
1) Min Å T[départ]
2) Indice Å Départ
3) Pour j de départ + 1 à N Faire
Si T[j] < Min Alors Min Å T[j]
indice Å j
Fin Si
Fin Pour
4) Cherche_Min Å indice
5) Fin Cherche_Min
4INFINFRC0003 Page 4
http://www.najah.com
Traitement :
- Pour permuter le contenu de deux variables, nous allons utiliser une troisième pour la
sauvegarde temporaire d'une des deux valeurs.
temp Å a
aÅb
b Å temp
Fin Anlyse
Algorithme
0) Procédure Permute (VAR a, b : Réel)
1) temp Å a
aÅb
b Å temp
2) Fin Permute
Algorithme
0) Procédure Affiche_Tab (T : Vect ; N : Entier)
4INFINFRC0003 Page 5
http://www.najah.com
1) Pour i de 1 à N Faire
Ecrite (T[i])
Fin Pour
2) Fin Affiche_Tab
Programme en Pascal
PROGRAM Tri_Selection ;
USES Crt ;
TYPE
Vect = ARRAY [1 .. 25 ] Of Real ;
VAR
N : Integer ;
T : Vect ;
{----------------------------------------------------------------------------------------}
PROCEDURE Saisie (VAR N : Integer );
BEGIN
Repeat
Write ('Entrer la taille du tableau : ') ;
ReadLn (N) ;
Until N In [4 .. 25 ] ;
END ;
{----------------------------------------------------------------------------------------}
PROCEDURE Remplir_Hasard (VAR T : Vect ; N : Integer ) ;
VAR i : Integer ;
BEGIN
Randomize ;
For i := 1 To N Do
T[i] := Random * 100 ;
END ;
{----------------------------------------------------------------------------------------}
FUNCTION Cherche_Min (T : Vect ; depart, N : Integer) : Integer ;
VAR
j, indice : Integer ;
Min : Real ;
BEGIN
4INFINFRC0003 Page 6
http://www.najah.com
Min := T[depart] ;
Indice := depart ;
For j := depart + 1 To N Do
Begin
If (T[j] < Min) Then Begin
Min := T[j] ;
indice := j ;
End ;
End ;
Cherche_Min := indice ;
End ;
{----------------------------------------------------------------------------------------}
PROCEDURE Permute (VAR a, b : Real ) ;
VAR Temp : Real ;
BEGIN
temp := a ;
a := b ;
b := temp ;
END ;
{----------------------------------------------------------------------------------------}
PROCEDURE Tri_Select (VAR T : Vect ; N : Integer ) ;
VAR
i, Pos_Min : Integer ;
BEGIN
For i := 1 To N-1 Do
Begin
Pos_Min := Cherche_Min (T, i, N) ;
If Pos_Min <> i Then Permute (T[i] , T[Pos_Min]) ;
End ;
END ;
{----------------------------------------------------------------------------------------}
PROCEDURE Affiche_Tab (T : Vect ; N : Integer) ;
VAR i : Integer ;
BEGIN
For i := 1 To N Do
WriteLn (T[i] : 8 : 3) ;
END ;
{= = = = = = = = = = = = = = = = = = P P = = = = = = = = = = = = = = = = = = = = = = }
BEGIN
Saisie (N) ;
Remplir_Hasard (T, N) ;
4INFINFRC0003 Page 7
http://www.najah.com
Tri_Select (T, N) ;
WriteLn ('Tableau trié " );
Affiche_Tab (T, N) ;
END.
*-*-*-*-*-*-*-*-*-*-*
Algorithme
0) Début Tri_Bulles
1) Proc Saisie (N)
2) Proc Remplir_Hasard (T, N)
3) Ecrire ("Tableau non trié ")
4) Proc Affiche_Tab (T, N)
5) Proc Bulles (T, N)
6 ) Ecrire ("Tableau trié ")
7) Proc Affiche_Tab (T, N)
8) Fin Tri_Sélection
Algorithme
0) Procédure Bulles (VAR T : Vect ; N : Entier)
1) Répéter
échange Å Faux
Pour i de 1 à N-1 Faire
Si (T[i] > T[i +1] ) Alors Proc Permute (T[i], T[i+1])
échange Å Vrai
Fin Si
Fin Pour
Jusqu'à échange = Faux
2) Fin Bulles
TYPE
Vect = ARRAY [1 .. 25 ] Of Real ;
VAR
N : Integer ;
T : Vect ;
4INFINFRC0003 Page 9
http://www.najah.com
{----------------------------------------------------------------------------------------}
PROCEDURE Saisie (VAR N : Integer );
BEGIN
Repeat
Write ('Entrer la taille du tableau : ') ;
ReadLn (N) ;
Until N In [4 .. 25 ] ;
END ;
{----------------------------------------------------------------------------------------}
PROCEDURE Remplir_Hasard (VAR T : Vect ; N : Integer ) ;
VAR i : Integer ;
BEGIN
Randomize ;
For i := 1 To N Do
T[i] := Random * 100 ;
END ;
{----------------------------------------------------------------------------------------}
PROCEDURE Permute (VAR a, b : Real ) ;
VAR Temp : Real ;
BEGIN
temp := a ;
a := b ;
b := temp ;
END ;
{----------------------------------------------------------------------------------------}
PROCEDURE Bulles (VAR T : Vect ; N : Integer ) ;
VAR
i : Integer ;
echange : Boolean ;
BEGIN
Repeat
echange := False ;
For i := 1 To N-1 Do
If (T[i] > T[i +1] ) Then
Begin
Permute (T[i], T[i+1]) ;
echange := True ;
End ;
Until (echange = False);
END ;
4INFINFRC0003 Page 10
http://www.najah.com
{----------------------------------------------------------------------------------------}
PROCEDURE Affiche_Tab (T : Vect ; N : Integer) ;
VAR i : Integer ;
BEGIN
For i := 1 To N Do
WriteLn (T[i] : 8 : 3) ;
END ;
{= = = = = = = = = = = = = = = = = = P P = = = = = = = = = = = = = = = = = = = = = = }
BEGIN
Saisie (N) ;
Remplir_Hasard (T, N) ;
WriteLn ('Tableau non trié ');
Affiche_Tab (T, N) ;
Bulles (T, N) ;
WriteLn ('Tableau trié ');
Affiche_Tab (T, N) ;
END.
Algorithme
0) Début Tri_Insertion
1) Proc Saisie (N)
4INFINFRC0003 Page 11
http://www.najah.com
Le principe global est d'insérer ième élément à sa bonne place dans la liste formée par les (i-1)
éléments qui le précèdent e qui sont déjà triés.
Cette action est répétée jusqu'au dernier élément (le Nième).
Pour i de 2 à N Faire
L'itération commence à partir de 2, car on considère que le premier élément est trié et qu'il
occupe sa place.
Algorithme
0) Procédure T_Insertion (VAR T : Vect ; N : Entier)
1) Pour i de 2 à N Faire
Tmp Å T[i]
jÅi
Proc Décaler (T, j, Tmp)
T[j] Å Tmp
Fin Pour
2) Fin T_Insertion
4INFINFRC0003 Page 12
http://www.najah.com
Algorithme
0) Procédure Décaler (VAR T : Vect; VAR p : Entier ; temporaire : Réel)
1) Tant que (T[p -1] > Temporaire) Faire
T[p] Å T[p-1]
p Å p -1
Fin tant que
2) Fin Décaler
TYPE
Vect = ARRAY [1 .. 25 ] Of Real ;
VAR
N : Integer ;
T : Vect ;
{----------------------------------------------------------------------------------------}
PROCEDURE Saisie (VAR N : Integer );
BEGIN
Repeat
Write ('Entrer la taille du tableau : ') ;
4INFINFRC0003 Page 13
http://www.najah.com
ReadLn (N) ;
Until N In [4 .. 25 ] ;
END ;
{----------------------------------------------------------------------------------------}
PROCEDURE Remplir_Hasard (VAR T : Vect ; N : Integer ) ;
VAR i : Integer ;
BEGIN
Randomize ;
For i := 1 To N Do
T[i] := Random * 100 ;
END ;
{----------------------------------------------------------------------------------------}
{----------------------------------------------------------------------------------------}
PROCEDURE T_Insertion (VAR T : Vect ; N : Integer) ;
VAR i, j: Integer ;
tmp : Real ;
BEGIN
For i:= 2 To N Do
Begin
Tmp := T[i] ;
j := i ;
Decaler (T, j, Tmp) ;
T[j] := Tmp ;
End ;
END ;
{----------------------------------------------------------------------------------------}
PROCEDURE Affiche_Tab (T : Vect ; N : Integer) ;
VAR i : Integer ;
BEGIN
For i := 1 To N Do
WriteLn (T[i] : 8 : 3) ;
END ;
4INFINFRC0003 Page 14
http://www.najah.com
{= = = = = = = = = = = = = = = = = = P P = = = = = = = = = = = = = = = = = = = = = = }
BEGIN
Saisie (N) ;
Remplir_Hasard (T, N) ;
WriteLn ('Tableau non trié ');
Affiche_Tab (T, N) ;
T_Insertion (T, N) ;
WriteLn ('Tableau trié ' );
Affiche_Tab (T, N) ;
END.
Le tri Shell est donc une amélioration du tri par insertion. Au lieu de faire un décalage de
tous les éléments, il fera un décalage par pas de P éléments, ce qui permet d'affiner le tri du
tableau et de faire moins de déplacements d'éléments.
Le tri Shell commence par un pas assez élevé et il le diminue au fur et à mesure jusqu'à
arriver à un pas de 1. Ceci permet de réduire le désordre donc de diminuer le travail aux
étapes suivantes. Le pas est diminué à l'aide d'une suite calculée.
Shell propose la suite d'incréments vérifiant P1 = 1, Pn+1 = 3Pn+1 en réalisant les tris du plus
grand incrément possible vers le plus petit.
4INFINFRC0003 Page 15
http://www.najah.com
et en s'assurant qu'il y a encore un nombre suffisant de composantes dans les sous tableaux
considérés.
Conclusion :
Le tri Shell trie chaque liste d'éléments séparés de P positions chacun avec le tri par insertion.
L'algorithme effectue plusieurs fois cette opération en diminuant le pas P jusqu'à un pas égal à
1 ce qui équivaut à trier tous les éléments ensemble (tri par insertion normal).
Activité
Ecrire un programme nommé Tri_Shell, qui permet le tri d'un tableau T de N réels, par la
méthode du tri Shell.
Comme dans les activités précédentes, ce programme :
- affiche le contenu du tableau non trié puis le contenu du tableau trié par ordre décroissant.
- Lit un entier N compris entre 4 et 25.
- Le tableau est remplit de façon aléatoire par N Réels.
*-*-*-*-*-*-*-*-*-*-*
Algorithme
0) Début Tri_Shell
1) Proc Saisie (N)
2) Proc Remplir_Hasard (T, N)
3) Ecrire ("Tableau non trié ")
4) Proc Affiche_Tab (T, N)
5) Proc Shell (T, N)
6 ) Ecrire ("Tableau trié ")
7) Proc Affiche_Tab (T, N)
8) Fin Tri_Shell
4INFINFRC0003 Page 16
http://www.najah.com
Pour chaque valeur du pas (P) calculé, on utilise un traitement répétitif à condition
d’arrêt appliqué à chacun des sous tableaux.
PÅ 1
Tant Que (P< N) Faire
P Å(3* P +1)
Pour i de P +1 à NFaire
Si T[i] n’est pas à sa place alors on réalise les actions suivantes :
- Ranger la valeur de T[i] dans la variable TMP
- Décaler vers la droite par un pas = P les valeurs de T[i - P], T[i-2* P], ...
Jusqu’à arriver à une valeur qui est inférieure à T[i].
- Affecter au dernier élément décalé la valeur de TMP
Pour avoir la valeur maximale du pas, on utilise une boucle à condition d’arrêt :
PÅ 1
Tant Que (P< N) Faire
P Å(3* P +1)
Fin Tant Que
Algorithme
Nous allons écrire côte à côte les deux tris. Le tri par insertion normal, c'est-à-dire avec un pas
= 1 et le tri Shell qui applique un pas P à ce même tri.
4INFINFRC0003 Page 17
http://www.najah.com
TYPE
Vect = ARRAY [1 .. 25 ] Of Real ;
VAR
N : Integer ;
T : Vect ;
{----------------------------------------------------------------------------------------}
PROCEDURE Saisie (VAR N : Integer );
BEGIN
Repeat
Write ('Entrer la taille du tableau : ') ;
ReadLn (N) ;
Until N In [4 .. 25 ] ;
END ;
{----------------------------------------------------------------------------------------}
PROCEDURE Remplir_Hasard (VAR T : Vect ; N : Integer ) ;
VAR i : Integer ;
BEGIN
Randomize ;
For i := 1 To N Do
T[i] := Random * 100 ;
END ;
{----------------------------------------------------------------------------------------}
PROCEDURE Shell (VAR T : Vect ; N : Integer) ;
VAR
P, c, pos : Integer ;
Tmp : Real ;
BEGIN
P := 1 ;
While ( P < N) Do
Begin
p := (3* P +1) ;
4INFINFRC0003 Page 18
http://www.najah.com
End ;
{----------------------------------------------------------------------------------------}
PROCEDURE Affiche_Tab (T : Vect ; N : Integer) ;
VAR i : Integer ;
BEGIN
For i := 1 To N Do
WriteLn (T[i] : 8 : 3) ;
END ;
{= = = = = = = = = = = = = = = = = = P P = = = = = = = = = = = = = = = = = = == = }
BEGIN
Saisie (N) ;
Remplir_Hasard (T, N) ;
WriteLn ('Tableau non trié ');
Affiche_Tab (T, N) ;
Shell (T, N) ;
WriteLn ('Tableau trié ');
Affiche_Tab (T, N) ;
END.
4INFINFRC0003 Page 19
http://www.najah.com
Principe
Le tri fusion est construit suivant la stratégie "diviser pour régner". Le principe de base est
que pour résoudre un gros problème, il est souvent plus facile de le diviser en petits problèmes
élémentaires. Une fois chaque petit problème résolu, il n'y a plus qu'à combiner les différentes
solutions pour résoudre le problème global.
La méthode "diviser pour régner" est tout à fait applicable au problème de tri : plutôt que de
trier le tableau complet, il est préférable de trier deux sous tableaux de taille égale, puis de
fusionner les résultats.
Un algorithme récursif est très pratique. En effet, les deux sous tableaux seront eux même
triés à l'aide de même algorithme de tri fusion. Un tableau ne comportant qu'un seul élément
sera considéré comme trié : c'est la condition de fin du tri (arrêt).
Etapes de l'algorithme :
- Division de l'ensemble de valeurs en deux parties
- Tri de chacun des deux ensembles
- Fusion des deux ensembles obtenus pour reconstituer le tableau trié.
Remarque :
Nous constatons que la méthode de tri par fusion nécessite un tableau intermédiaire aussi
grand que le tableau initial à trier et c'est là où réside le principal inconvénient.
Exemple
Soit le tableau T Suivant :
T 12 3 0 15 -5 22 23 -7 10 8 8 12 34 35 3
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
T1 12 3 0 15 -5 22 23 T2 -7 10 8 8 12 34 35 3
1 2 3 4 5 6 7 1 2 3 4 5 6 7 8
T1 -5 0 3 12 15 22 23 T2 -7 3 8 8 10 12 34 35
1 2 3 4 5 6 7 1 2 3 4 5 6 7 8
On propose d'utiliser la méthode de tri par fusion pour fusionner T1 et T2. Le résultat sera
rangé dans le tableau T.
Etape 1
On commence par :
- comparer le premier élément de chacun des deux tableaux T1 et T2
Le plus petit est T2 [1] = -7
- placer -7 dans T [1] et se pointer à l'élément n°2 de T2
4INFINFRC0003 Page 20
http://www.najah.com
T -7
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Etape 2
- comparer le premier élément de T1 et le deuxième élément de T2
Le plus petit est T1 [1] = -5
- placer -5 dans T [2] et se pointer à l'élément n°2 de T1
- se pointer à l'élément n°3 de T
T -7 -5
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Etape 3
- comparer T1 [2] et T2 [2]
Le plus petit est T1 [2] = 0
- placer 0 dans T [3] et se pointer à l'élément n°3 de T1
- se pointer à l'élément n°4 de T
T -7 -5 0
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
- On poursuit la fusion de cette façon jusqu'à la fin de l'un des deux tableaux.
T -7 -5 0 3 3 8 8 10 12 12 15 22 23
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Tous les éléments du tableau T1 ont été rangés dans le tableau T, il ne reste que des éléments
dans le tableau T2. Ces éléments vont être transférés directement dans le tableau T.
T -7 -5 0 3 3 8 8 10 12 12 15 22 23 34 35
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Activité
On propose d'écrire un programme qui réalise la méthode de tri décrite précédemment (diviser
le tableau uniquement en 2 sous tableaux, sans appliquer la méthode complète du tri par
fusion, c'est-à-dire sans les divisions jusqu'à un tableau à 1 seul élément).
- La saisie de N, le remplissage du tableau et l'affichage sont les mêmes que les activités
précédentes.
*-*-*-*-*-*-*-*-*-*-*
4INFINFRC0003 Page 21
http://www.najah.com
Algorithme
0) Début Tri_Fus1
1) Proc Saisie (N)
2) Proc Remplir_Hasard (T, N)
3) Ecrire ("Tableau non trié ")
4) Proc Affiche_Tab (T, N)
5) Proc Fus (T, N)
6 ) Ecrire ("Tableau trié ")
7) Proc Affiche_Tab (T, N)
8) Fin Tri_Fus1
N1 Å N DIV 2
N2 Å N - N1
- Diviser le tableau en deux sous tableaux presque égaux.
Pour i de 1 à N1 Faire
T1[i] Å T[i]
Fin Pour
Pour i de 1à N2 Faire
T2[i] Å T1[N1 + i]
Fin Pour
Fin Analyse
Algorithme
0) Procédure Diviser (T : Vect ; N : Entier, VAR T1, T2 : Vect2 ; VAR N1, N2 : Entier)
1) N1 Å N DIV 2
2) N2 Å N - N1
3) Pour i de 1 à N1 Faire
T1[i] Å T[i]
Fin Pour
4) Pour i de 1à N2 Faire
T2[i] Å T1[N1 + i]
Fin Pour
5) Fin Diviser
Algorithme
0) Procédure Trier (VAR Tx : Vect2 ; taille : Entier)
1) Pour i de 1 à taille-1 Faire
4INFINFRC0003 Page 23
http://www.najah.com
- Ranger le reste des éléments du tableau T1 ou T2 (il s'agit d'une action de copie)
Si (c1 > n1) Alors {tous les éléments de T1 ont été rangés dans T,
il reste à copier les éléments de T2}
Pour i de c2 à N2 Faire
T[c] Å T2[i]
Inc (c, 1)
Fin Pour
Sinon {copier le reste des éléments de T2}
Pour i de c1 à N1 Faire
T[c] Å T1[i]
Inc (c, 1)
Fin Pour
Fin Si
Fin Analyse
4INFINFRC0003 Page 24
http://www.najah.com
Algorithme
0) Procédure Fusionner (VAR T : Vect ; N : Entier ; T1, T2 : Vect2 ; N1, N2 : Entier)
1) c Å 0
2) c1 Å 1
3) c2 Å 1
4) Répéter
Inc (c, 1)
Si (T1 [c1] < T2 [c2])
Alors
T[c] Å T1 [c1]
Inc (c1, 1)
Sinon
T[c] Å T2 [c2]
Inc (c2, 1)
Fin Si
Jusqu'à (c1 > N1) OU (c2 > N2)
TYPE
Vect = ARRAY [1 .. 25 ] Of Real ;
Vect2 = ARRAY [1.. (25 DIV 2) +1] Of Real ;
VAR
N, N1, N2 : Integer ;
4INFINFRC0003 Page 25
http://www.najah.com
T : Vect ;
T1, T2 : Vect2;
{----------------------------------------------------------------------------------------}
PROCEDURE Saisie (VAR N : Integer );
BEGIN
Repeat
Write ('Entrer la taille du tableau : ') ;
ReadLn (N) ;
Until N In [4 .. 25 ] ;
END ;
{----------------------------------------------------------------------------------------}
PROCEDURE Remplir_Hasard (VAR T : Vect ; N : Integer ) ;
VAR i : Integer ;
BEGIN
Randomize ;
For i := 1 To N Do
T[i] := Random * 100 ;
END ;
{----------------------------------------------------------------------------------------}
PROCEDURE Diviser (T : Vect ; N : Integer ; VAR T1, T2 : Vect2 ; VAR N1, N2 :
Integer) ;
VAR i : Integer ;
BEGIN
N1 := N DIV 2 ;
N2 := N - N1 ;
For i := 1 TO N1 Do
T1[i] := T[i] ;
For i := 1 TO N2 Do
T2[i] := T[N1 + i] ;
END ;
{----------------------------------------------------------------------------------------}
PROCEDURE Fusionner (VAR T : Vect ; N : Integer ; T1, T2 : Vect2 ; N1, N2 : Integer) ;
VAR
c, c1, c2, i : Integer ;
BEGIN
c := 0 ; c1 := 1; c2 := 1 ;
Repeat
If (T1 [c1] < T2 [c2]) Then Begin
T[c] := T1 [c1] ;
Inc (c1, 1) ;
4INFINFRC0003 Page 26
http://www.najah.com
End
Else
Begin
T[c] := T2 [c2] ;
Inc (c2, 1) ;
End ;
Inc (c, 1) ;
Until (c1 > N1) OR (c2 > N2) ;
If (c1 > N1) Then
For i := c2 TO N2 Do
Begin
T[c] := T2[i] ;
Inc (c, 1) ;
End
Else
For i := c1 TO N1 Do
Begin
T[c] := T1[i] ;
Inc (c, 1) ;
End ;
END ;
{----------------------------------------------------------------------------------------}
PROCEDURE Trier (VAR Tx : Vect2 ; taille : Integer ) ;
VAR
i, j : Integer ;
Aux : Real ;
BEGIN
For i := 1 TO taille-1 Do
For j := i+1 TO taille Do
If (Tx[i] > Tx[j]) Then Begin
aux := Tx[i] ;
Tx[i] := Tx[j] ;
Tx[j] := aux ;
End ;
END ;
{----------------------------------------------------------------------------------------}
PROCEDURE Fus (VAR T : Vect; N : Integer) ;
BEGIN
Diviser (T, N, T1, T2, N1, N2) ;
Trier (T1, N1) ;
Trier (T2, N2) ;
Fusionner (T, N, T1, T2, N1, N2) ;
END ;
{----------------------------------------------------------------------------------------}
PROCEDURE Affiche_Tab (T : Vect ; N : Integer) ;
VAR i : Integer ;
4INFINFRC0003 Page 27
http://www.najah.com
BEGIN
For i := 1 To N Do
WriteLn (T[i] : 8 : 3) ;
END ;
{= = = = = = = = = = = = = = = = = = P P = = = = = = = = = = = = = = = = = = == = }
BEGIN
Saisie (N) ;
Remplir_Hasard (T, N) ;
WriteLn ('Tableau non trié ');
Affiche_Tab (T, N) ;
Fus (T, N) ;
WriteLn ('Tableau trié ' );
Affiche_Tab (T, N) ;
END.
Application :
Reprendre le programme précédent et remplacer la procédure de tri classique par une
procédure de tri_fusion selon le principe "diviser pour régner". Cette procédure fait appel à la
procédure fusion.
PROGRAM Tri_Fusion2 ;
USES WinCrt ;
TYPE
Tab = ARRAY [1 .. 25 ] Of Real ;
VAR
N, N1, N2 : Integer ;
T : Tab ;
{----------------------------------------------------------------------------------------}
PROCEDURE Saisie (VAR N : Integer );
BEGIN
Repeat
Write ('Entrer la taille du tableau : ') ;
ReadLn (N) ;
Until N In [4 .. 25 ] ;
END ;
{----------------------------------------------------------------------------------------}
PROCEDURE Remplir_Hasard (VAR T : Tab ; N : Integer ) ;
VAR i : Integer ;
4INFINFRC0003 Page 28
http://www.najah.com
BEGIN
Randomize ;
For i := 1 To N Do
T[i] := Random * 100 ;
END ;
4INFINFRC0003 Page 29
http://www.najah.com
{----------------------------------------------------------------------------------------}
PROCEDURE Affiche_Tab (T : Tab ; N : Integer) ;
VAR i : Integer ;
BEGIN
For i := 1 To N Do
WriteLn (T[i] : 8 : 3) ;
END ;
{= = = = = = = = = = = = = = = = = = P P = = = = = = = = = = = = = = = = = = == = }
BEGIN
Saisie (N) ;
Remplir_Hasard (T, N) ;
WriteLn ('Tableau non trié ');
Affiche_Tab (T, N) ;
Tri_Fusion (T, N) ;
WriteLn ('Tableau trié ' );
Affiche_Tab (T, N) ;
END.
4INFINFRC0003 Page 30
http://www.najah.com
4INFINFRC0003 Page 31
http://www.najah.com
CHAPITRE 4
LES ALGORITHMES RECURRENTS
I/ Introduction :
Un algorithme ou un traitement est dit récurrent s’il utilise un procédé itératif ou récursif
pour engendrer un résultat qui dépend de 1 ou plusieurs résultats précédents, on parle alors
d’un algorithme ou d’un traitement récurrent d’ordre.
*-*-*-*-*-*-*-*-*-*-*
Réponse à la question 2 :
1- Pour calculer la somme des éléments d'une matrice, nous devons cumuler la totalité de ses
éléments. Le cumul nécessite une initialisation à zéro de la variable de calcul, ici Somme. Un
parcourt, de toute les lignes et les colonnes est donc nécessaire pour lire le contenu des cases
et les ajouter chaque fois à la somme.
Somme Å somme + M[ligne, colonne]
Puisque ce traitement fait toujours référence à l’élément précédent, donc c’est un traitement
récurent d’ordre 1.
4INFINFRC0004 Page 1
http://www.najah.com
Fin Pour
Fin Pour
Fin Analyse
Traduction en Pascal
FUNCTION Somme_Matrice (M : MAT; N : Integer) : Integer ;
VAR Somme, ligne, colonne : Integer ;
Begin
Somme := 0;
For ligne := 1 To N Do
Begin
For colonne := 1 To N Do
Begin
Somme := Somme + M[ligne, colonne] ;
End ;
End ;
Somme_Matrice := Somme ;
End;
Activité
Suite de Thue-Morse
4INFINFRC0004 Page 2
http://www.najah.com
U0 Æ "0"
U1 Æ "01"
U2 Æ "0110"
U3 Æ "01101001"
U4 Æ "0110100110010110"
U5 Æ "0110 1001100101100110100110010110"
*-*-*-*-*-*-*-*-*-*-*
Réponse à la question 1 :
Le premier résultat dépend de la première valeur du caractère ("0" ou "1"), un deuxième
résultat est obtenu à partir du premier trouvé, et ainsi de suite. On conclu que c'est une suite
récurrente d’ordre 1.
2- Analyse
4INFINFRC0004 Page 3
http://www.najah.com
Traduction en Pascal
PROGRAM Suite_Thue_Morse ;
USES Crt ;
VAR N : Integer ;
A : Char ;
4INFINFRC0004 Page 4
http://www.najah.com
{------------------------------------------------------------------------------------}
PROCEDURE Saisie (VAR N : Integer ; VAR A: Char );
Begin
Repeat
Write('Donner le nombre d''éléments de la suite : ');
readLn (N);
Until N In [2 .. 100] ;
Repeat
Write('Donner un caractère 0 ou 1 : ');
readLn (A);
Until A In ['0', '1'] ;
End;
{------------------------------------------------------------------------------------}
FUNCTION Thue_Morse (N: Integer; A : Char ) : String ;
VAR Ch : String ;
i, j, L : Integer ;
Begin
Ch := A ;
For i := 1 To N Do
Begin
j := 1 ;
Repeat
If Ch [j] = '0' Then Insert ('1', Ch, j+1)
Else Insert ('0', Ch, j+1);
L := Length (Ch) ;
j := j+ 2;
Until j > l ;
End;
Thue_Morse := Ch ;
End ;
4INFINFRC0004 Page 5
http://www.najah.com
0:1 (a+b)0 = 1
1:11 (a+b)1 = 1*a + 1*b
2:121 (a+b)2 = 1*a2 + 2*a*b + 1*b2
3 : 1 3 3 1 (a+b)3 = 1*a3 + 3*a2*b + 3*a*b2 + 1*b3
4 : 1 4 6 4 1 (a+b)4 = 1*a4 + 4*a3*b + 6*a2*b2 + 4*a*b3 + 1*b4
On obtient chaque coefficient en additionnant le nombre qui lui est situé au-dessus ainsi que
celui qui lui est situé au-dessus à gauche.
Ligne 1 1
Ligne 2 1 1
Ligne 3 1 2 1
Colonnes
1 2 3
Ligne 1 1
Ligne 2 1 1
Ligne 3 1 2 1
Ligne 4 1 3 3 1
Ligne 5 1 4 6 4 1
Colonnes
1 2 3 4 5
On constate que le calcul du contenu de la case (3,2) fait référence au contenu de deux cases
précédentes. C'est un traitement récurrent d'ordre 2.
Lecture :
La tradition attribue le nom de triangle de Pascal au triangle décrit plus haut. Cependant, ce
triangle était déjà connu en Orient et moyen Orient plusieurs siècles avant la publication de
Blaise Pascal. Il était ainsi connu des mathématiciens persans, par exemple al-Karaji (953 -
1029)
ou Omar Khayam au XIe siècle qui l'utilisent pour développer (a + b)n
Activité
4INFINFRC0004 Page 6
http://www.najah.com
Questions
1/ Est-ce que ce traitement est récurrent ?
Dans l’affirmative donnez son rang.
2- Ecrire un programme nommé Triangle_de_Pascal, Qui affiche pour un nombre de lignes
compris entre 1 et 20 (3 ≤ N ≤ 20), deux fois le triangle. Le premier triangle est obtenu par
traitement itératif et le second par un traitement récursif.
*-*-*-*-*-*-*-*-*-*-*
1/ L'exemple ci-dessous montre que le calcul du contenu de la case (3, 2) fait référence au
contenu de deux cases précédentes. C'est un traitement récurrent d'ordre 2.
2/ Analyse du problème
4INFINFRC0004 Page 7
http://www.najah.com
Algorithme
0) Procédure Triangle_itératif (N: Entier; VAR MAT : Matrice);
1) MAT [1,1] Å 1
2) MAT [2,1] Å 1
3) MAT [2,2] Å 1
4) Pour ligne de 3 à N Faire
MAT [ligne, 1] Å 1
MAT [Ligne, Ligne] Å 1
Pour colonne de 2 à ligne -1 Faire
MAT [ligne, colonne] Å MAT [ligne - 1, colonne] + MAT [ligne -1 , colonne -
1]
Fin Pour
Fin Pour
5) Fin Triangle_itératif
4INFINFRC0004 Page 8
http://www.najah.com
Algorithme
0) Procédure Triangle_récursif (N : Entier ; VAR MAT : matrice)
1) Pour ligne de 1 à n Faire
Pour colonne de 1 à ligne Faire
Mat [ligne, colonne] ← Fn Val_Triangle (colonne, ligne)
FinPour
FinPour
2) Fin Triangle_récursif
Algorithme
0) Fonction Val_Triangle (x, y : Entier) : Entier
1) Si (x = 1) OU (y = x) Alors Val_Triangle ← 1
Sinon Val_Triangle ← Fn Val_Triangle (x, y - 1) + Fn Val_Triangle (x - 1, y - 1)
Finsi
2) Fin Val_Triangle
4INFINFRC0004 Page 9
http://www.najah.com
Traitement : On utilise deux boucles : une pour les lignes et une autre pour les colonnes afin
d'afficher le contenu de la matrice.
Fin Analyse
Traduction en Pascal
PROGRAM Triangle_de_Pascal ;
USES Crt ;
CONST
max = 20;
TYPE
Matrice = ARRAY[1.. 20, 1.. 20] Of Integer ;
VAR
N : Integer ;
MAT : Matrice ;
{------------------------------------------------------------------------------------}
PROCEDURE Saisie (VAR N : Integer );
BEGIN
Repeat
Write ('Nombre de lignes du triangle : ');
ReadLn (N) ;
Until N IN [3.. max] ;
END ;
{------------------------------------------------------------------------------------}
PROCEDURE Triangle_iteratif (N: Integer; VAR MAT : Matrice);
VAR
ligne, colonne : Integer ;
BEGIN
MAT [1,1] := 1 ;
MAT [2,1] := 1 ;
4INFINFRC0004 Page 10
http://www.najah.com
MAT [2,2] := 1 ;
For ligne := 3 To N Do
Begin
MAT [ligne, 1] := 1;
MAT [Ligne, Ligne] := 1;
For colonne := 2 To ligne -1 Do
Begin
MAT [ligne, colonne] := MAT [ligne - 1, colonne] + MAT [ligne -1 , colonne - 1];
End ;
End ;
END ;
{------------------------------------------------------------------------------------}
FUNCTION Val_Triangle (x, y : Integer) : Integer ;
BEGIN
If (x = 1) OR (y = x) Then Val_Triangle := 1
Else Val_Triangle := Val_Triangle (x, y - 1) + Val_Triangle (x - 1, y - 1) ;
END ;
{------------------------------------------------------------------------------------}
PROCEDURE Afficher_Triangle (n : Integer; MAT : matrice);
VAR ligne, colonne : Integer ;
BEGIN
For ligne := 1 To N Do
Begin
For colonne := 1 To ligne Do
Begin
Write(Mat [ligne, colonne]:2,' ') ;
End;
WriteLn ;
End;
END ;
{------------------------------------------------------------------------------------}
PROCEDURE Triangle_recursif (N : Integer; VAR MAT : Matrice) ;
VAR ligne, colonne : Integer ;
BEGIN
For ligne := 1 To N Do
For colonne := 1 To ligne Do
Mat [ligne, colonne] := Val_Triangle (colonne, ligne) ;
END;
4INFINFRC0004 Page 11
http://www.najah.com
Saisie (N) ;
WriteLn ('Triangle de Pascal - Traitement itératif ');
Triangle_iteratif (N, MAT) ;
Afficher_Triangle (N, MAT) ;
WriteLn;
WriteLn('Triangle de Pascal - Traitement récursif ');
Triangle_recursif (N, MAT);
Afficher_Triangle (N, MAT) ;
END.
V/ La suite de Fibonacci
Léonard de Pise, plus connu sous le nom de Fibonacci, étudia du point de vue numérique la
reproduction des lapins. L'unité de base est un couple de lapins, il considère qu'un couple de
jeunes lapins met une saison pour devenir adulte, attend une deuxième saison de gestation,
puis met au monde un couple de jeunes lapins à chaque saison suivante. En supposant que les
lapins ne meurent jamais, et lorsque l'on met côte à côte le nombre de couples de lapins à
chaque saison, cela donne... la suite de Fibonacci :
La suite de Fibonacci est une suite récurrente dont chaque élément obéit à la relation de
récurrence :
Un = Un-1 + Un-2
4INFINFRC0004 Page 12
http://www.najah.com
Avec U1 = 1 et U2 = 1
Activité 1
Ecrire un programme qui, pour un entier N donné, calcule le Nième terme de la suite de
Fibonnaci.
Un = Un-1 + Un-2 Avec U1 = 1 et U2 = 1
Donner une solution itérative, sans avoir recourt à un tableau, utilisant une fonction
nommée Fibo_Itérative.
N étant un entier compris entre 1 et 50.
*-*-*-*-*-*-*-*-*-*-*
Algorithme
0) Début Suite_itérative_Fibonacci
1) Proc Saisie (N)
2) Valeur_suite Å Fn Fibo_Itérative (N)
3) Ecrire ("Fibo de ", N , " = " ,Valeur_Fibo)
4) Fin Suite_itérative_Fibonacci
4INFINFRC0004 Page 13
http://www.najah.com
- Cette suite est récurrente d'ordre 2. On doit initialiser ses deux premiers termes.
U1 = 1
U2 = 1
- Donc on constate que si N ≤ 2, le dernier terme de la suite est égal à 1
Si N ≤ 2 Alors Fibo Å 1
- Sinon on calcule cette suite par une itération de 3 à N
Fibo Å u1 + u2
u1 Å u2
u2 Å Fibo
Algorithme
0) Fonction Fibo_Itérative (N : Entier) : Entier Long
1) U1 Å 1
2) U2 Å 1
3) Si N ≤ 2 Alors Fibo Å 1
Sinon
Pour i de 3 à N Faire
Fibo Å U1 + U2
U1 Å U2
U2 Å Fibo
Fin Pour
Fin Si
5) Fibo_Itérative Å Fibo
6) Fin Fibo_Itérative
Traduction en Pascal
PROGRAM Suite_iterative_Fibonacci ;
USES Crt ;
CONST
Nmax = 50 ;
VAR
Valeur_Fibo : LongInt ;
N : Integer ;
4INFINFRC0004 Page 14
http://www.najah.com
{-----------------------------------------------------------------------------}
PROCEDURE Saisie (VAR N : Integer);
BEGIN
Repeat
Write ('N = ');
ReadLn (N);
Until N IN [1.. Nmax] ;
END ;
{-----------------------------------------------------------------------------}
FUNCTION Fibo_Iterative (N : Integer ) : LongInt ;
VAR
U1, U2, i : Integer ;
Fibo : LongInt ;
BEGIN
U1 := 1 ;
U2 := 1 ;
If N <= 2 Then Fibo := 1
Else
For i := 3 To N Do
Begin
Fibo := U1 + U2 ;
U1 := U2 ;
U2 := Fibo ;
End ;
Fibo_Iterative := Fibo ;
END ;
{============ P P ===================}
BEGIN
ClrScr ;
Saisie (N) ;
Valeur_Fibo := Fibo_Iterative (N);
WriteLn ('Fibo de ', N , ' = ' ,Valeur_Fibo) ;
END.
Activité 2
Remplacer dans le programme précédent la fonction Fibo_Itérative par une autre
fonction réalisant le même traitement itératif mais en utilisant pour le calcul, un
tableau d'entiers long.
Cette fonction sera nommée Fibo_Tab.
*-*-*-*-*-*-*-*-*-*-*
4INFINFRC0004 Page 15
http://www.najah.com
Algorithme
0) Fonction Fibo_Tab (N : Entier ; T : Tab) : Entier Long
1) T[1] Å 1
2) T[2] Å 1
3) Si N ≤ 2 Alors Fibo Å 1
Sinon
Pour i de 3 à N Faire
T[i] Å T[i-1] + T[i-2]
Fin Pour
Fibo Å T[n]
Fin Si
4) Fibo_Tab Å Fibo
5) Fin Fibo_Tab
4INFINFRC0004 Page 16
http://www.najah.com
Activité 3
Remplacer dans le programme précédent la fonction Fibo_Tab par une autre fonction
réalisant le même traitement mais cette fois avec un procédé récursif.
Cette fonction sera nommée Fibo_Récursive.
*-*-*-*-*-*-*-*-*-*-*
3/ Solutions récursive :
4INFINFRC0004 Page 17
http://www.najah.com
Algorithme
0) Fonction Fibo_Récursive (N : Entier ) : Entier Long
1) Si N ≤ 2 Alors Fibo_Récursif Å 1
Sinon Fibo_Récursif Å Fn Fibo_Récursif (N-1) + Fn Fibo_Récursif (N-2)
Fin Si
2) Fin Fibo_Récursif
Fib (n + 1)
La suite (Vn) définie sur N* par Vn = semble converger vers le nombre d'or
Fib (n)
1+ 5
ϕ= dont une valeur approchée est 1,618.
2
Exemples pour n de 1 à 7:
4INFINFRC0004 Page 18
http://www.najah.com
On a vu précédemment que :
La suite de Fibonacci est une suite de nombres entiers. Voici le début de cette suite :
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, ... jusqu'à l'infini.
Un nombre de la suite est le résultat de la somme de ses deux précédents (U3 = U1 + U2).
Voici maintenant pourquoi le nombre d'or et la suite de Fibonacci sont étroitement liés:
Activité
Ecrire une fonction nommé Nombre_Or, qui retourne une approximation du nombre d'or avec
une précision de 10-6
*-*-*-*-*-*-*-*-*-*-*
3) Nombre_Or Å V[i]
4) Fin Nombre_Or
4INFINFRC0004 Page 20
http://www.najah.com
CHAPITRE 5
LES ALGORITHMES
D'ARITHMETIQUE
Tout est nombre
Pythagore (vers 570 / 480 av. J.-C.)
I/ Introduction :
D'après le dictionnaire :
Arithmétique
(nom féminin)
Science des nombres.
[adjectif] Qui a rapport à l'arithmétique.
Donc l'arithmétique est une partie des mathématiques qui étudie les relations entre les
nombres et les opérations élémentaires entre eux ainsi que les techniques permettant de les
manipuler.
L'arithmétique faisait partie de la géométrie des Grecs anciens: études des nombres
figurés.
L'adoption de la numération de position à base dix fait réaliser d'immenses progrès,
même si :
9 La base 2 est universelle pour les ordinateurs
9 La base 12 subsiste pour les heures
9 La base 60 pour les angles et les durées en minutes et secondes
Activité 1
Ecrire une fonction nommé PGCD_Euclide, qui renvoie le PGCD de deux entiers a et b
strictement positifs on appliquant l'algorithme d'Euclide.
Analyse
Résultat = PGCD_Euclide
Traitement :
Le PGCD de deux entiers a et b est le plus grand entier permettant de diviser a et b.
Nous allons appliquer l'algorithme d'Euclide :
Si a = b, le PGCD est a (ou b)
4INFINFRC0005 Page 1
http://www.najah.com
Algorithme
0) Fonction PGCD_Euclide (a, b : entier ) : Entier
1) Tant Que (b ≠ 0) Faire
r Å a MOD b
aÅb
bÅr
Fin Tant Que
2) PGCD_Euclide Å a
3) Fin PGCD_Euclide
Traduction en Pascal
FUNCTION PGCD_Euclide (a, b: Integer) : Integer ;
VAR r : Integer ;
BEGIN
While (b < > 0) DO
Begin
r := a MOD b ;
a := b ;
b := r;
End;
PGCD_EUCLIDE := a ;
END;
Activité 2
Proposez une version récursive de la fonction PGCD en utilisant la méthode de la différence.
Cette méthode par différences est parfois appelée anthyphérésie ou anthyphérèse (du grec
anthy = à son tour, tour à tour et aphairesis = action d'enlever, supprimer).
Exemple :
Pour a = 22 et b = 6
4INFINFRC0005 Page 2
http://www.najah.com
Traitement :
On remarque que :
Si a > b alors a Å a-b
Sinon b Å b -a
Ce traitement est répéter tant que a ≠ b donc c'est un traitement itératif, mais nous voulons un
traitement récursif :
On peut dire que Si a = b Alors PGCD 'an b) = a
Sinon Si a > b Alors PGCD (a, b) = PGCD (a-b, b)
Sinon PGCD (a, b) = PGCD (a, b-a)
Ce traitement est récursif.
Fin Analyse
Algorithme
0) Fonction PGCD (a, b : Entier ) : Entier ;
1) Si a = b Alors PGCD Å a
Sinon Si (a > b) Alors PGCD Å FN PGCD (a-b, b)
Sinon PGCD Å FN PGCD (a, b-a)
Fin Si
2) Fin PGCD
Traduction en Pascal
p
II-2 - Calcul de A n (Arrangement)
4INFINFRC0005 Page 3
http://www.najah.com
Définition :
On appelle arrangement de p éléments pris parmi n, tout p-uplet d'éléments distincts d'un
ensemble à n éléments.
p
A n = n * (n-1) * (n -2) * …. *(n- p +1)
n!
=
(n − p )!
Activité
p
Ecrire un programme nommé Arrangement permettant d'afficher l'arrangement ( A ) de
n
deux entiers n et p sachant que 1 ≤ p ≤ n.
Algorithme
0) Début Arrangement
1) Proc saisie (n, p)
2) anp Å Fn Arrange (n, p)
3) Ecrire ("A(n, p) = ", anp )
4) Fin Arrangement
Jusqu'à (1 ≤ p ≤ n )
Fin Saisie
Algorithme
0) Procédure Saisie (VAR n, p : Entier)
1) Répéter
Lire (n)
Lire (p)
Jusqu'à (1 ≤ p ≤ n )
2) Fin Saisie
Algorithme
0) Fonction arrange ( n, p : Entier) : Entier
1) ar Å 1
2) Pour i de n à n-p+1 (pas -1 ) Faire
ar Å ar * i
Fin Pour
3) arrange Å ar
4) Fin arrange
Programme Pascal
PROGRAM Arrangement ;
USES Crt ;
VAR
n, p, anp : Integer ;
4INFINFRC0005 Page 5
http://www.najah.com
{---------------------------------------------------------------}
PROCEDURE Saisie (VAR n, p : Integer );
BEGIN
Repeat
Write('N = ') ; ReadLn (n) ;
Write ('P = '); ReadLn (p) ;
Until (1 <= p) AND (p <= n );
END;
{---------------------------------------------------------------}
FUNCTION Arrange ( n, p : Integer ) : Integer ;
VAR
ar, i : Integer ;
BEGIN
ar := 1 ;
For i := n DownTo (n-p+1) Do
ar := ar * i ;
Arrange := ar ;
End ;
{ ========== P P =================}
BEGIN
Saisie (n, p) ;
anp := Arrange (n, p) ;
WriteLn ('A(n, p) = ', anp ) ;
END.
p
II-3 - Calcul de C n Combinaison de p éléments parmi n
D'après le dictionnaire :
> combinaison
(nom féminin)
Assemblage, arrangement de choses dans un ordre déterminé.
Mesures que l'on prend pour réussir dans une entreprise.
Union de plusieurs corps qui forment un composé.
Sous-vêtement féminin.
Vêtement de travail.
Définition :
C'est le nombre de permutations sans ordre possibles de p éléments parmi n.
4INFINFRC0005 Page 6
http://www.najah.com
p
C np = An / p! = n! / p!(n-p)!
n et p sont des entiers qui vérifient la condition 0 ≤ p ≤ n
Activité
Ecrire un programme nommé Combinaison permettant d'afficher la combinaison C np de deux
entiers n et p sachant que 0 ≤ p ≤ n.
Algorithme
0) Début Combinaison
1) Proc Saisie (n, p)
2) cnp Å Fn Combin (n, p)
3) Ecrire ("C(n, p) = ", cnp)
4) Fin Combinaison
4INFINFRC0005 Page 7
http://www.najah.com
Algorithme
0) Procédure Saisie (VAR n, p : Entier)
1) Répéter
n = Donnée
p = Donnée
Jusqu'à (0 ≤ p ≤ n )
2) Fin Saisie
Algorithme
0) Fonction Combin (n, p : Entier) : Réel
1) combin Å Fn Factorielle (n) / ( Fn Factorielle (p) * Fn Factoreille (n-p ) )
2) Fin Combin
4INFINFRC0005 Page 8
http://www.najah.com
Programme Pascal
PROGRAM Combinaison ;
USES Crt ;
VAR
n, p : Integer ;
cnp : Real ;
{---------------------------------------------------------------}
PROCEDURE Saisie (VAR n, p : Integer );
BEGIN
Repeat
Write ('N = ') ; ReadLn (n) ;
Write ('P = '); ReadLn (p) ;
Until (01 <= p) AND (p <= n );
END;
{---------------------------------------------------------------}
FUNCTION Factorielle (a : Integer ) : LongInt ;
VAR
i : Integer ;
F : LongInt ;
BEGIN
F := 1 ;
For i := 2 TO a Do
F := F * i ;
Factorielle := F ;
END ;
{---------------------------------------------------------------}
FUNCTION Combin (n, p : Integer ) : Real ;
BEGIN
Combin := Factorielle (n) / ( Factorielle (p) * Factorielle (n-p ) )
END ;
{ ========== P P =================}
BEGIN
Saisie (n, p) ;
cnp := Combin (n, p) ;
WriteLn ('C(n, p) = ', cnp ) ;
END.
4INFINFRC0005 Page 9
http://www.najah.com
D'après le dictionnaire :
BASE : En numération, indique le nombre de chiffres utilisé dans un système. On parle par
exemple d'une base hexadécimale quand on utilise un système à 16 chiffres.
Désigne aussi, dans un tableau, le plus petit élément de ce tableau, souvent le 0 ou le 1.
C'est également le raccourci pour désigner une base de données.
Définition :
On appelle système de numération l'ensemble des règles nécessaires pour écrire les nombres.
Les quatre systèmes de numération les plus utilisés sont : le décimal, l'hexadécimal, l'octal et
le binaire.
Un système de numération utilise une base de numération qui est un entier supérieur ou égal à
2.
Soit B une base de numération, le système de cette base comporte des chiffres allant de 0 à B-
1, dés fois on a recours aux caractères A, B, … lorsque B est supérieur à 10.
Exemples :
Base Système Chiffres et caractères utilisés
2 Binaire 0 et 1
8 Octal 0, 1, 2, 3, 4, 5, 6 et 7
10 Décimal 0, 1, 2, 3, 4, 5, 6, 7, 8 et 9
16 Hexadécimal 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F
NB : Les procédures suivantes de conversion peuvent être remplacées par des fonctions s'il
n'y a pas l'action d'affichage.
Activité 1
Conversion du décimal au binaire
1/ Ecrire une procédure nommé Dec_Bin, qui convertit un nombre décimal en son équivalent
Binaire.
2/ Insérer cette procédure dans un programme nommé Conversions, traduire et tester ce
programme.
4INFINFRC0005 Page 10
http://www.najah.com
Algorithme
0) Procédure Dec_Bin (D : Entier; VAR Restes : Tab ; VAR C : Entier)
1) C Å 0
2) Répéter
CÅC+1
Restes [C] Å D MOD 2
D Å D DIV 2
Jusqu'à (D = 0)
3) Ecrire (D, "En décimal vaut ")
Pour i de C à 1 (pas -1) Faire
Ecrire (Retes [i] )
Fin Pour
Ecrire ( " en binaire")
4) Fin Dec_Bin
Algorithme
0) Début Conversions
1) Proc Saisie (D)
2) Proc Dec_Bin (D, Restes, C)
3) Fin Conversions
Algorithme
0) Procédure Saisie_Decimal (VAR D : Entier )
1) Répéter
Ecrire ("Entrer un entier positif ")
Lire (D)
4INFINFRC0005 Page 11
http://www.najah.com
Jusqu'à (D > 0)
2) Fin Saisie
Traduction en Pascal
PROGRAM Conversions ;
USES Crt ;
TYPE
Chiffre = 0..9 ;
TAB = ARRAY [ 1.. 100 ] Of Chiffre ;
VAR
D, C : Integer ;
Restes : TAB ;
{---------------------------------------------------------------------}
PROCEDURE Saisie_Decimal (VAR D : Integer );
BEGIN
Repeat
Write ('Entrer un entier positif ');
ReadLn (D);
Until (D > 0) ;
END ;
{---------------------------------------------------------------------}
PROCEDURE Dec_Bin (D : Integer ; VAR Restes : Tab ; VAR C : Integer );
VAR i : Integer ;
BEGIN
Write (D, ' En décimal vaut ');
Repeat
C := C + 1;
Restes [C] := D MOD 2;
4INFINFRC0005 Page 12
http://www.najah.com
D := D DIV 2 ;
Until (D = 0 ) ;
For i:= C DownTo 1 Do
Write(Retes [i]);
4INFINFRC0005 Page 13
http://www.najah.com
Activité 2
Conversion de l'hexadécimal au binaire
1/ Ecrire une procédure nommé Hex_Bin, qui convertit un nombre Hexadécimal en Binaire.
2/ Intégrer cette procédure au programme Conversions.
1 8 B F
= = = =
0001 1000 1001 1111
- Le nombre hexadécimal contient des caractères donc il doit être de type chaîne de
caractères.
- Chaque caractère de la chaîne doit être convertit en binaire, lui aussi sous forme d'une autre
chaîne de caractères. L'ensemble sera concaténé dans chaîne nommée Ch_Binaire.
- La conversion des caractères en caractères binaire sera assurée par la fonction Car_Binaire.
Fin Analyse
Algorithme
0) Procédure Hex_Bin (Hex : Chaîne ; VAR Ch_Binaire : Chaîne )
1) Ch_Binaire Å ""
2) Pour i de 1 à Long (Hex) Faire
Ch_Binaire Å Ch_Binaire + Fn Car_Binaire ( Hex[i] )
Fin Pour
3) Ecrire (hex, " En hexadécimal, vaut ", Ch_Binaire, " en binaire")
4) Fin Hex_Bin
4INFINFRC0005 Page 14
http://www.najah.com
Algorithme
0) Fonction Car_Binaire ( car : Caractère ) : Chaîne
1) Si Non (Car DANS ["0" .. "9"])
Alors N Å Ord (Car) - 55
Sinon Valeur (Car, N, Erreur)
Fin Si
2) Ch Å "0000"
3) i Å 4
4) Répéter
r Å N MOD 2
ConvCh (r, Ch_Reste)
Ch[i] Å Ch_Reste [1]
4INFINFRC0005 Page 15
http://www.najah.com
N Å N Div 2
iÅi-1
Jusqu'à (N = 0)
5) Car_Binaire Å Ch
6) Fin Car_Binaire
Algorithme
0) Procédure Saisie_Hexa (VAR Hex : Chaîne )
1) Répéter
Ecrire ("Entrer un nombre hexadécimal : ")
Lire (Hex)
Jusqu'à (Long (Hex) > 0)
2) Fin Saisie
4INFINFRC0005 Page 16
http://www.najah.com
Car : Char ;
{---------------------------------------------------------------------}
PROCEDURE Saisie_Decimal (VAR D : Integer );
BEGIN
Repeat
Write ('Entrer un entier positif ');
ReadLn (D);
Until (D > 0) ;
END ;
{---------------------------------------------------------------------}
PROCEDURE Dec_Bin (D : Integer ; VAR Restes : Tab ; VAR C : Integer );
VAR i : Integer ;
BEGIN
Write (D, ' En décimal vaut ');
Repeat
C := C + 1;
Restes [C] := D MOD 2;
D := D DIV 2 ;
Until (D = 0 ) ;
For i:= C DownTo 1 Do Write (Retes [i]);
WriteLn(' en binaire') ;
END;
4INFINFRC0005 Page 17
http://www.najah.com
Ch := '0000' ;
i := 4 ;
Repeat
r := N MOD 2 ;
STR (r, Ch_Reste) ;
Ch[i] := Ch_Reste [1] ;
N := N DIV 2 ;
i := i - 1 ;
Until (N = 0) ;
Car_Binaire := Ch ;
END ;
Writeln('*******************************************************');
Saisie_Hexa (Hex);
Hex_Bin (Hex, Ch_Binaire);
END.
Activité 3
Conversion du binaire en octal
Ecrire une fonction nommé Bin_Oct, qui convertit un nombre Binaire en son équivalent
Octal.
4INFINFRC0005 Page 18
http://www.najah.com
Résultat = Bin_Oct
Traitement :
- Le nombre binaire est sous forme de chaîne de caractères (ch_binaire), on extrait une partie
de 3 bits à partir du dernier chiffre (dernier en commençant de la droite)
L Å Long (Ch_binaire)
Ch_tmp Å Sous_chaîne (Ch_binaire, L -2, 3)
- Convertir chaque caractères de la chaîne Ch1 obtenu en un chiffre numérique (a) puis lui
appliquer le système de pondération (puissance de 2) à l'aide d'une fonction nommé
Puissance_2 et le cumuler avant la précédent, au départ init à zéro.
Oct_tmp Å 0 {initialisation pour le cumul}
Pour j de 1 à 3 Faire
Valeur (Ch_tmp [j], a, erreur )
Oct_tmp Å Oct_tmp + (a * Fn Puissance_2 (3 - j) )
Fin Pour
- Convertir le chiffre obtenu en un caractère pour pouvoir le concaténer dans la variable de
conversion en octal.
ConvCh (Oct_tmp, Ch_oct_tmp)
Au départ, Ch_oct_tmp est initialisée à vide.
- Concatener ch_oct_tmp à la variable de convertion
Oct Å Ch_oct_tmp + Oct
Au départ, Oct est initialisée à vide.
- Répéter ce traitement pour une autre tranche de 3 caractères et ce jusqu'à finir la totalité de
la chaîne Ch_binaire.
LÅL-3
- Ajouter, si nécessaire, des "0" à gauche de la chaîne Ch_binaire de façon que sa longueur
soit divisible par 3.
Fin
Algorithme
0) Fonction Bin_Oct (Ch_binaire : Chaîne) : Chaîne
1) Tant Que (Long (Ch_binaire) MOD 3 ≠ 0) Faire
Ch_binaire Å "0" + Ch_binaire
Fin Tant Que
2) Oct Å ""
Ch_oct_tmp Å ""
4INFINFRC0005 Page 19
http://www.najah.com
L Å Long (Ch_binaire)
N Å L DIV 3
3) Pour i de 1 à N Faire
Ch_tmp Å Sous_chaîne (Ch_binaire, L -2, 3)
Oct_tmp Å 0
Pour j de 1 à 3 Faire
Valeur (Ch_tmp [j], a, erreur )
Oct_tmp Å Oct_tmp + (a * Fn Puissance_2 (3 - j) )
Fin Pour
4INFINFRC0005 Page 20
http://www.najah.com
Algorithme
0) Fonction Puissance_2 (x Entier) : Entier
1) v Å 1
2) Pour i de 1 à x Faire
vÅv*2
Fin Pour
Puissance_2 Å v
3) Fin Puissance_2
Programme Pascal
PROGRAM Binaire_Octal ;
USES Crt ;
VAR
N, L, i, j, a, Oct_tmp, erreur : Integer ;
ch_binaire, Ch_oct_tmp, Ch_tmp, oct : String ;
test : boolean ;
{-------------------------------------------------------------------------}
FUNCTION Puissance_2 (x: Integer) : Integer ;
VAR i,v : Integer ;
BEGIN
v := 1 ;
For i:= 1 To x Do
v := v * 2 ;
Puissance_2 := v;
END ;
{-------------------------------------------------------------------------}
FUNCTION Bin_Oct (Ch_binaire : String) : String;
BEGIN
While (Length (Ch_binaire) MOD 3 <> 0) Do
Begin
Ch_binaire := '0' +Ch_binaire ;
END;
Oct := '';
4INFINFRC0005 Page 21
http://www.najah.com
Ch_oct_tmp := '';
L := Length (Ch_binaire) ;
N := L DIV 3 ;
For i:= 1 To N Do
Begin
Ch_tmp := Copy (Ch_binaire, L -2, 3) ;
Oct_tmp := 0 ;
For j := 1 To 3 Do
Begin
Val (Ch_tmp [j], a, erreur );
Oct_tmp := Oct_tmp + (a * Puissance_2 (3 - j) ) ;
END;
{ ========= P P ============== }
BEGIN
Activité 4
Conversion d'une base B en une base B2
Ecrire un programme modulaire nommé B1_B2, qui permet de convertir un nombre N d'une
base B1 en une base B2.
Sachant que ( 2 ≤ B1 ≤ 16) et ( 2 ≤ B1 ≤ 16) et (B1 ≠ B2).
4INFINFRC0005 Page 22
http://www.najah.com
Fin Analyse
4INFINFRC0005 Page 23
http://www.najah.com
4INFINFRC0005 Page 24
http://www.najah.com
4) Convert_B10 Å D10
5) Fin Convert_10
Algorithme
0) Fonction Puissance_B1 (x , B1 : Entier) : Entier
1) v Å 1
2) Pour i de 1 à x Faire
v Å v * B1
Fin Pour
Puissance_B1 Å v
3) Fin Puissance_2
4INFINFRC0005 Page 25
http://www.najah.com
- Bien sur, si le reste de la division est supérieur à 10, on applique la relation sur les codes
ASCII, mais au lieu de chercher comme précédemment le code ASCII du caractère (Ord(
CHR (..) -55 )), On cherche Le caractère dont le code ASCII est 55 + Reste.
Répéter
Reste Å NB10 MOD B2
Si Reste > 10 Alors Ch_Reste Å Majuscule (CHR (55 + R))
Sinon ConvCh (Reste, ch_Reste )
Fin SI
Ch Å Ch_Reste + Ch
NB10 Å NB10 DIV B2
Jusqu'à (NB10 = 0)
Fin Analyse
Algorithme
0) Fonction Convert_B2 (NB10 : Entier Long ; B2 : Entier) : Chaîne
1) Ch Å ""
2) Répéter
Reste Å NB10 MOD B2
Si Reste > 10 Alors Ch_Reste Å Majuscule (CHR (55 + Reste))
Sinon ConvCh (Reste, ch_Reste)
Fin SI
Ch Å Ch_Reste + Ch
NB10 Å NB10 DIV B2
Jusqu'à (NB10 = 0)
3) Convert_B2 Å Ch
4) Fin Convert_B2
Algorithme
0) Procédure Lecture (VAR B1, B2 : Entier)
1) Répéter
Ecrire ("Base 1 = ")
4INFINFRC0005 Page 26
http://www.najah.com
Lire (B1)
Jusqu'à (2 ≤ B1 ≤ 16)
2) Répéter
Ecrire ("Base 2 = ")
Lire (B2)
Jusqu'à (2 ≤ B2 ≤ 16) ET ((B2 ≠ B1)
3) Fin Lecture
Répéter
{On suppose que le nombre NB1 est correct}
Test Å Faux
{Lecture de NB1}
Ecrire ("Donner le nombre de la base ", B1, " : ")
Lire (NB1)
{On extrait une sous chaîne formée uniquement par les caractères de la base B1}
Ch Å Sous_chaîne ( NBX, 1, B1 )
{On vérifie si tout les caractères de NB1 sont présent dans la chaîne Ch.
Si un seul caractère n'appartient pas à Ch, le test prend Vrai et on doit recommencer.
Avant le test les caractères de NB1 sont convertit en majuscule.
Pour i de 1 à Long (NB1) Faire
NB1 [i] Å Majuscule (NB1[i] )
Si Position (NB1[i], Ch) = 0 Alors Test Å Vrai
Fin Si
Fin Pour
Jusqu'à test = Faux.
Fin Analyse
Algorithme
0) Procédure Saisie_NB1 (B1 : Entier VAR NB1 : Chaîne)
1) Répéter
Test Å Faux
Ecrire ("Donner le nombre de la base ", B1, " : ")
Lire (NB1)
4INFINFRC0005 Page 27
http://www.najah.com
Ch Å Sous_chaîne ( NBX, 1, B1 )
Pour i de 1 à Long (NB1) Faire
NB1 [i] Å Majuscule (NB1[i] )
Si Position (NB1[i], Ch) = 0 Alors Test Å Vrai
Fin Si
Fin Pour
Jusqu'à test = Faux.
2) Fin Saisie_NB1
Programme Pascal
PROGRAM B1_B2 ;
USES Crt ;
VAR
B1, B2 : Integer ;
NB1, NB2 : String ;
NB10 : LongInt ;
{------------------------------------------------------------}
PROCEDURE Lecture (VAR B1, B2 : Integer );
BEGIN
Repeat
Write('Base 1 = ');
ReadLn (B1);
Until (B1 IN [2 .. 16 ]);
Repeat
Write('Base 2 = ');
ReadLn (B2);
Until (B2 IN [2 .. 16 ]) and (B1 <> B2);
END ;
{------------------------------------------------------------}
PROCEDURE Saisie_NB1 (B1 : Integer ; VAR NB1 : String );
CONST
4INFINFRC0005 Page 28
http://www.najah.com
NBX = '0123456789ABCDEF';
VAR
Test : Boolean ;
i : Integer ;
ch : String [16];
BEGIN
Repeat
Test := False ;
Write ('Donner le nombre de la base ', B1,' : ');
ReadLn (NB1);
{------------------------------------------------------------}
FUNCTION Puissance_B1 (x , B1 : Integer) : Integer ;
VAR i, v : Integer ;
BEGIN
v := 1;
For i := 1 To x Do
v := v * B1 ;
Puissance_B1 := v ;
END ;
{------------------------------------------------------------}
FUNCTION Convert_B10 (NB1 : String; B1 : Integer) : LongInt ;
VAR
D10 : LongInt ;
L, i, N, erreur : Integer ;
BEGIN
D10 := 0 ;
L := Length (NB1) ;
For i := L DownTo 1 Do
Begin
If (NB1[i] ) IN ['A' .. 'F']
Then N := Ord (NB1[i]) - 55
4INFINFRC0005 Page 29
http://www.najah.com
{------------------------------------------------------------}
FUNCTION Convert_B2 (NB10 : LongInt ; B2 : Integer) : String ;
VAR
Ch, Ch_Reste : String ;
Reste : Integer ;
BEGIN
Ch := '' ;
Repeat
Reste := NB10 MOD B2 ;
If (Reste > 10) Then Ch_Reste := UpCase (CHR(55 + Reste))
Else STR (Reste, ch_Reste) ;
Ch := Ch_Reste + Ch ;
NB10 := NB10 DIV B2 ;
Until (NB10 = 0) ;
Convert_B2 := Ch ;
END ;
{------------------------------------------------------------}
FUNCTION Convert (NB1 : String; B1, B2 : Integer) : String ;
VAR
NB10 : Integer;
Ch_B2 : String ;
BEGIN
NB10 := Convert_B10 (NB1, B1) ;
Ch_B2 := Convert_B2 (NB10, B2) ;
Convert := Ch_B2 ;
WriteLn
END ;
{=============== P P =========================}
BEGIN
Lecture (B1, B2);
Saisie_NB1 (B1, NB1);
NB2 := Convert (NB1, B1, B2) ;
WriteLn (NB1, ' écrit dans la base ', B1, ' vaut : ', NB2, ' Dans la base ', B2) ;
END.
4INFINFRC0005 Page 30
http://www.najah.com
Par 2
Si le dernier chiffre est 0, 2, 4, 6 ou 8 c'est-à-dire paire, le nombre est divisible par 2
Par 3
Si la somme des chiffres du nombre est divisible par 3, le nombre est divisible par 3.
Par 4
Si on considère N2 le nombre formé par les deux derniers chiffres (Exemple N = 446, N2 est
donc 46). N est divisible par 4 si N2 est divisible par 4.
Par 5
Il suffit que le dernier chiffre soit divisible par 5.
Par 6
Un nombre est divisible par 6 s'il est divisible à la fois par 2 ET par 3
Par 7
On s'appuie sur le fait que si le nombre abcd est divisible par 7, alors:
abc-2*d est divisible par 7, et réciproquement.
Exemple 1 : Soit le nombre 7241.
Nous conservons tous les chiffres sauf le dernier, et nous lui retranchons deux fois le dernier
: 724 - 2*1 = 722.
Nous procédons de même avec le résultat, soit 722 : 72 - 2*2 = 68.
Or 68 n'est pas divisible par 7, donc 7241 non plus.
Par 9
De même que pour 3, il suffit que la somme des chiffres qui composent le nombre soit
divisible par 9.
Exemples :
5019 n'est pas divisible par 9 c a r (5 + 0 + 1 + 9 =15 or 15 n'est pas divisible par 9)
837 est divisible par 9 car (8 + 3 + 7 = 18 et 18 est divisible par 9).
4INFINFRC0005 Page 31
http://www.najah.com
CHAPITRE 6
Un algorithme désigne une suite structurée et finie d’actions qui, appliquée à une donnée,
permet d’aboutir de façon certaine à un résultat déterminé, solution d’un problème donné.
Voilà l’objet de ce cours, qui se présente sous la forme d’exercices corrigés quelques notions
d'approximations pour répondre aux questions précédentes.
D'après le dictionnaire :
Approximation, nom féminin :
Sens 1 = Evaluation, estimation d'un résultat, d'une valeur ou d'une grandeur
Sens 2 = Valeur imprécise, valeur approchée.
I/ Approximation de π :
Le nombre π n'est pas égal à 3.14. Cette valeur n'est qu'une approximation qui peut être
suffisante pour la majorité des calculs.
Exemples d'approximation de π
D’après le site http://pi.lacim.uqam.ca/fra/approximations_fr.html
Approximation de Pi Expression
3.14159265358979323846264338327972661934754988088 log(262537412640768744)/sqrt(163)
3.14159292035398230088495575221238938053097345132 355/113
3.14159265358979323232482478168718522102495836130 3+1/8+1/61+1/5020+1/128541455
3.14285714285714285714285714285714285714285714286 22/7
3.14159265297229778439562243903476832945058472332 log(5280)/sqrt(67/9)
3.14159434945008183015994893408428386595324120871 log(2198)/sqrt(6)
3.14153985278295351258699144235404432987724178693 43^(7/23)
3+1/8+1/(8*8)+1/(8*8*17)+ 1/(8*8*17*19)+
3.14159265350877192982456140350877192982456140351
1/(8*8*17*19*300)
3.14159265359494408765142414297178409903697305215 log(60318/13387)*48/23
4INFINFRC0006 Page 1
http://w
www.najaah.com
3.141592678809890117154475085702107112151731572449665 (
(13/4)^(1181/1216)
3.141592653358677810789901935775387110931409289997070 (2288+16/1329)^(1/41) + 2
3.141592653358979323846626492014552556041530465119371 ( 2766948199753963/226588)^(1/158) + 2
3.14159265334925537281127154977950557427981092445613 (63023/305110)*(1/3)+1/4+
+1/2*(sqrt(5)+1)
3.14163154662592052545159991271030998351101174556654 log(20+Pi))
3.141592595508835562119942907929503119861222069220605 6
689/396/ln(689 /396)
3.141592652258264612520060371796440222371557877998317 (2143/22)^(1/4)
Activitéé
On se proopose de calcculé une appproximation de π en utiliisant la form
mule d'Euler.
n=10 3,0493
n=100 3,1320
n=1 000 3,1406
n=10 000
0 3,141497
97
15
n=10 3,14159
92653589792
228
π2 /6 = 1+ 1/2
22 + 1/32 + ….
… + 1/ n2 + ….
Analysee
Résultat = Ecrire ("V Valeur approochée de PI est
e ", Valeurr)
Traitemeent :
On remarrque que le calcul
c de la somme
s comm mence par laa valeur 1, donc on peut initialiser laa
variable S1S à 1 et com
mmencer l'itération et le cumul à parrtir de la valeeur 2.
On calculle la somme suivante daans la variablle S2 (le succcesseur de S S1 suivant laa formule).
On cherche une approoximation enntre les deuxx expressionns (RacineCaarrée (6*S1) et
RacineCaarrée (6*S2) ) de telle faaçon que leurr différence soit inférieuure à une valeeur minimale
fixée à l'aavance (epsilon) et qui détermine
d la précision dee l'approximaation.
S2 Å 1
iÅ2
Répéter
4INFINFRC0006 Pagee 2
http://www.najah.com
S1 Å S2
S2 Å S1 + 1/ Carré (i)
iÅi+1
Jusqu'à (RacineCarrée (6 * S2) - RacineCarrée (6 * S1) ) < Epsilon
Valeur Å RacineCarrée (6 * S2)
Algorithme
0) Début PI_Euler
1) Répéter
Ecrire ("Entrer la valeur d'Epsilon ")
Lire (Epsilon)
Jusqu'à (Epsilon > 10-8) ET (Epsilon < 10-3)
3) S2 Å 1
4) i Å 2
5) Répéter
S1 Å S2
S2 Å S1 + 1/ Carré(i)
iÅi+1
Jusqu'à (RacineCarrée(6 * S2) - RacineCarrée (6 * S1) ) < Epsilon
6) Valeur Å RacineCarrée(6 * S2)
7) Ecrire ("Valeur approchée de PI est ", Valeur )
8) Fin PI_Euler
Traduction en Pascal
PROGRAM PI_Euler ;
USES Crt ;
VAR
i : LongInt ;
S1, S2, valeur : REAL ;
Epsilon : REAL ;
4INFINFRC0006 Page 3
http://w
www.najaah.com
BEGIN
ClrScr ;
Repeat
Write ('Entrer la valeur
v d''Epsiilon : ') ;
ReadLLn (Epsilon) ;
U
Until (Epsilonn > 10 E-8) AND
A (Epsiloon < 10E-3) ;
S22 := 1 ;
i :=
: 2;
Repeat
S1 := S2
S ;
S2 := S1
S + 1/ Sqr (i) ;
i := i + 1 ;
U
Until (SqrT(6 * S2) - SqrT
T (6 * S1) ) < Epsilon ;
Exerciice :
Calcul d'uune série
On veut calculer
c une valeur approochée de la ssérie suivantte :
Avvec U0 =1 et
e Un = (x/nn)Un-1
Ecrire unn programmee nommé Un ne_Série, quii affiche unee valeur apprrochée de cettte série pouur
une variaable x comprrise par exem
mple entre -550 et 50 ainsi que le nom
mbre d'itératioons
effectuéees pour une valeur
v inférieeure à une prrécision EPS
S donnée.
4INFINFRC0006 Pagee 4
http://www.najah.com
- Une procédure ENTREE pour saisir au clavier la valeur de la variable x et appliquer les
tests de saisie nécessaires.
- EPS sera déclaré comme une constante ayant pour commencer une valeur 10-6.
Fin Analyse
Algorithme
0) Début Une_Série
1) Proc Entrée (x)
2) Proc Calcul (x, s, n)
3) Ecrire (" X = ", x , " S = ",s , " avec ", n, " itérations avec une précision ", EPS)
4) Fin Une_Série
Algorithme
0) Procédure ENTREE (VAR x : Réel)
1) Répéter
x = Donnée ("Entrer la valeur de x entre -50 et 50 ")
Jusqu'à (x ≥ -50) ET (x ≤ 50)
2) Fin ENTREE
4INFINFRC0006 Page 5
http://w
www.najaah.com
- Cumuleer la valeur de
d s sÅ s+U
Fin Anallyse
Algorith
hme
0) Procéd dure CALC CUL ( x : Réeel; VAR s : R
Réel; VAR n : Entier)
1) U Å 1;
1 n Å 0; s Å 0
2) Répéteer
nÅn+1
U Å U * x/n
sÅs+U
Jusqu'àà ABS ((s- (ss-U)) /s) < EPS
E
3) Fin CA ALCUL
Program
mme Pasccal
PROGRA AM Une_S Série ;
USES Crrt ;
CONST
EPPS = 1E-6;
VAR
x,, s : Real;
n : Integer;
{------------------------------------------------------------------------------------------}
PROCED DURE Entrrée (VAR x : Real);
BEGIN
Repeat
Write ( 'Entrez x entree -50 et 550 : ') ;
ReadL Ln ( x );
U
Until ( x >= - 50) AND (x ( <= 80);
END;
{------------------------------------------------------------------------------------------}
PROCED DURE Calcul (x : Rael; VAR s : Raael ; VAR n : Integer) ;
4INFINFRC0006 Pagee 6
http://www.najah.com
VAR
U : Real;
BEGIN
U := 1;
Repeat
Inc (n);
U := U * x /n ;
s := s + U;
Until Abs ((s - (s - U)) /s ) < EPS;
END ;
{ ===================== P. P =========================}
BEGIN
ClrSscr;
Saisie (x);
Calcul (x, s, n);
WriteLn (' X = ', x , ' S = ',s , ' avec ', n, ' itérations avec une précision ', EPS)
END.
4INFINFRC0006 Page 7
http://www.najah.com
CHAPITRE 7
Ce principe général produit des algorithmes qui permettent souvent d'importantes réductions
de complexité.
Activités :
II/ Algorithme de tri : Tri rapide (QuickSort) :
Principe :
C’est un algorithme classique de tri, considéré comme l'un des plus rapides, des plus simples
et des plus efficaces. C’est un "Tri par segmentation" basée sur la méthode de conception
"diviser pour régner", appelé aussi "Tri de Hoare" (du nom de son inventeur).
Une Solution
L’idée de l’algorithme est très simple. Etant donné un vecteur d’éléments à trier :
1. Choisir un élément arbitraire du tableau, que nous appelons élément pivot.
2. Réorganiser les éléments du tableau de sorte que tous les éléments inférieurs au
pivot soient à gauche du pivot, les éléments supérieurs au pivot soient à droite du
pivot, ceux qui sont égaux soit à gauche soit à droite et le pivot choisi entre les
deux. Cette opération s’appelle partition.
3. Trier récursivement la partie gauche et la partie droite du tableau jusqu’à obtenir
uniquement des sous tableaux à un seul élément.
4INFINFRC0007 Page 1
http://www.najah.com
T 10 6 8 13 19 2 1 31 3 11
Pivot
Pivot
T 10 6 8 13 19 2 1 31 3 11
G P
Permuter G et P
¾ On contenue le balayage par la gauche et le balayage par la droite tant que les
éléments sont bien placés en échangeant à chaque fois les éléments mal placés.
¾
1 2 3 4 I=5 6 J=7 8 9 10
Pivot
T 10 6
8 3 19 2 1 31 13 11
Permuter
La construction des deux sous-listes est terminée quand l’indice (I) montant devient
égal à l’indice descendant (J).
1 2 3 4 I=5 I=J=6 J=7 8 9 10
Pivot
T 1 2
10 6 8 3 19 31 13 11
4INFINFRC0007 Page 2
http://www.najah.com
Pivot
T
10 6 8 3 1 2 19 31 13 11
Permuer
4INFINFRC0007 Page 3
http://www.najah.com
Pivot
T
2 6 8 3 1 10 19 31 13 11
Sous-liste1 Sous-liste2
Le pivot est à sa place définitive. Il reste à trier récursivement (de la même manière) la liste1 et la
liste2
Activité
Ecrire une analyse et un algorithme une procédure pour trier en ordre croissant un tableau T
de n entiers en utilisant la méthode de tri rapide.
Analyse de la procédure Tri_rapide
Résultat = Tableau trié
Traitement : deb représente le point de départ gauche et fin représente le point de
départ droit.
le pivot est le premier élément du tableau
On utilise deux compteurs temporaires : i pour avancer à partir de deb+1 et j pour reculer
à partir de fin. Initialement : I Å deb+1 , jÅ fin
1. Nous cherchons à partir de I le premier élément supérieur au pivot s’il existe
Tant que (T[i] < T[deb]) et (i < j) Faire
i Å i+1
Fin tant que
2. Nous cherchons à partir de j le premier élément inférieur au pivot s’il existe
Tant que (T[j] > T[deb]) et (i < j) Faire
j Å j-1
Fin tant que
3. Si les indices des deux éléments sont différents alors on permute leurs contenus, on avance
i de 1 et on recule j de 1.
Si i < j Alors
Proc Permut (T[i], T[j])
i Å i+1
j Å j-1
Fin Si
On répète ce traitement 1, 2 et 3 jusqu’à croisement de i et j ( j <= i)
On permute le pivot avec l’élément du croisement : Proc Permut (T[deb], T[j])
Le pivot est à sa place définitive. Il reste à trier récursivement la liste1à gauche du pivot
(Du deb à j-1) et la liste2 à droite du pivot (de j+1 à fin) :
Proc Tri_rapide (deb, j-1,T)
Proc Tri_rapide (j+1, fin)
4INFINFRC0007 Page 4
http://w
www.najaah.com
Algorith
hme de la procédure
p e Tri_rapid
de
0) Début Procédure Tri_rapide
T (ddeb, fin : enttier; VAR T : Tab)
1) Si deb < fin Alors
iÅdebb+1
jÅ finn
REPETER
Tant que
q (T[i] < T[deb])
T et (i < j) Faire
i Å i+1
i
Fin tannt que
Tant que
q (T[j] > T[deb])
T et (i < j) Faire
j Å j-1
Fin tannt que
Si i < j Alors
Proc Permmut (T[i], T[j])
i Å i+1
j Å j-1
Fin Si
JUUSQU’à i >=> j
Si T[j]] > T[deb] Alors
A j Å j-1
Prroc Permut (T[deb],
( T[j]])
Prroc Tri_rapidde (deb, j-1,T)
Prroc Tri_rapidde (j+1, fin, T)
Fin Sii
2) Fin Trri_rapide
Tableau
u de codification des objets
o locau ux
Objeets Type/Natur
T e Rôlee
I, j Enttier Comptteur
Permut Procédure Permetttant de perrmuter les vvaleurs de deux
d
variablles
Un jeu mis
m au point par p Edouard Lucas en 18883. Il
consiste een 3 piquets,, le premier ccomporte n disque
d de
tailles touutes différenntes, empilés du plus gran
nd (en bas) au
a
plus petitt (en haut). Le
L problème des tours dee Hanoï
consiste à faire passer tous ces diisques au piqquet 2, en s'aaidant du troisième piqueet, sachant
qu'on ne déplace qu'uun disque à la
l fois, et en respectant laa règle suivaante : aucun disque ne
doit être empilé
e sur un
u disque de diamètre infférieur.
La légende
Le jeu original était accompagné
a d'une noticee racontant la légende dee moines d'uun temple de
Hanoï quui passaient leur
l temps à résoudre ce jeu pour atteindre le nirrvana (l'extinnction, ici onn
désigne fin
f du mondee). En effet, les moines ccroyaient quee la fin du monde
m arriverait lorsque le
4INFINFRC0007 Pagee 5
http://w
www.najaah.com
jeu seraitt achevé. Leuur jeu grandeeur nature occcupait la coour d'un tempple. Il se com
mposait de 64
6
disques d'or
d et de 3 tiiges d'ivoire d'un mètre de d haut.
Nous alloons voir que ce jeu, souss ses allures ssimples, peuut demander pas mal de temps
t avant
d'être résolu. C'est un
n vrai casse-ttête. Mais, aalors qu'un êttre humain m
mettra du tem mps à arriverr
au bout de
d ce jeu, l'orrdinateur va trouver en quelques
q secondes la soluution, simplement en
utilisant une
u règle, biien pratique en informatiique et en mathématique
m e : la récursivvité.
Voici dee gauche à drroite les anneeaux à déplaacer quand ono dispose dee 1 à 4 anneaaux.
Constattations :
L'étude dud schéma prrécédant mon ntre que le jeeu est toujou
urs possible et demande deux fois
plus de teemps chaquee fois que l'oon ajoute un disque à la tour
t initiale.
En effet, si l'on sait réésoudre le prroblème pouur 3 disques (en 7 coups)), en transpoortant les
anneaux de d la tour A vers la tour B, alors on sait résoudree le problèm me pour 4 dissques. Ainsi,
on transpporte les 3 disques de la tour
t A vers lla tour B (7 coups),
c puis on déplace le quatrièmee
disque dee la tour A vers la tour C (1 coup) et enfin on traansporte les 3 disques de la tour B
vers la toour C (7 coupps). Le nombbre de coupss devient le double,
d plus un ; ici il esst devenu :
7+1+7 =115 soit 2x7+ +1. Le nombrre de coups ccroît de faço on très rapidee.
Il existe un
u algorithmme récursif trrès classiquee pour résouddre ce problèème. Suppossons qu'on
sache dépplacer n-1 diisques. Pour en déplacer n, il suffit de
d déplacer (n-1)
( disquess du piquet 1
au piquett 3, puis de déplacer
d le grand disque du piquet 1 au piquet 2, on termine en déplaçannt
les (n-1) autres disqu
ues du piquett 3 vers le piquet 2.
Activitéés :
a- A partir du schémaa précédent, donnez, souus forme de texte, une soolution pourr un jeu à 3
disques
(N =3).
4INFINFRC0007 Pagee 6
http://www.najah.com
b- Donnez le nombre de déplacement de disques pour arriver à l'état final puis en déduire
celui pour N disques.
c- Ecrivez une analyse d'une procédure récursive nommée Hanoï donnant la marche à suivre
pour résoudre le problème avec N, le nombre de disques initial compris entre 1 et 64.
d- Déduisez l’algorithme correspondant,
e- Ecrivez un programme complet en Pascal.
Solution :
a- On choisit l'ordre des piquets comme suit :
Le piquet initial est A, le piquet final est B et l'intermédiaire est C.
Opérations de déplacement :
1/ disque 1 de piquet A vers piquet B
2/ disque 2 de piquet A vers piquet C
3/ disque 1 de piquet B vers piquet C
4/ disque 3 de piquet A vers piquet B
5/ disque 1 de piquet C vers piquet A
6/ disque 2 de piquet C vers piquet B
7/ disque 1 de piquet A vers piquet B
Le tableau suivant précise le nombre de coups en bases 2 et 10 selon que la tour comprend de
un à huit disques.
Disques 1 2 3 4 5 6 7 8
Base 2 1 11 111 1111 11 111 111 111 1 111 111 11 111 111
Base 10 1 3 7 15 31 63 127 255
Analyse
En regardant bien les déplacements effectués, on constate les choses suivantes :
- si on a "n" disques à déplacer :
- on déplace "N-1" disques vers le taquet intermédiaire
4INFINFRC0007 Page 7
http://www.najah.com
On peut dire que ce jeu est un traitement récursif. La règle du jeu est simple (ne pas déposer
un disque sur un disque plus petit), la solution l'est aussi.
Algorithme
0) Procédure Hanoï (n : entier ; départ, cible, intermédiaire : caractère)
1) Si (n > 0) Alors
Hanoï (n-1, départ, intermédiaire, cible)
Ecrire ("Disque du taquet ", départ " vers le taquet ", intermédiaire)
Hanoï (n-1, cible, départ, intermédiaire)
Fin Si
2) Fin Hanoï
4INFINFRC0007 Page 8
http://www.najah.com
{--------------------------------------------------------------------------------}
PROCEDURE Hanoi (n: Integer ; depart, but, inter : Char);
BEGIN
If (n > 0) Then
Begin
Hanoi (n-1, depart, inter, but) ;
WriteLn ('déplacer un disque de ', depart, ' en ', inter) ;
Hanoi (n-1, but, depart, inter) ;
End;
END ;
Activité
Retournons à la légende des tours de Hanoï qui dit que des moines sont en train de déplacer
les 64 disques vers l'un des deux autres piquets, au rythme de quelques secondes par disque et
quand ils auront terminé, ce sera la nirvana (la fin du monde).
Question
Cherchez combien de temps leur faudra t'il pour atteindre terminer les déplacements et le
temps qu'il nous reste à vivre avant la fin du monde.
Solution
Disons qu'il faut aux moines au moins 4 secondes pour déplacer 1 disques (le jeu est en
grandeur nature). Ca fait donc 3600/4 = 900 déplacements par heure.
Imaginons qu'ils jouent jour et nuit à ce jeu donc 900 * 24h = 21600 déplacements par jour.
Mais ils ont 64 disques, d'où 264-1 déplacements, soit à peu prés 1,8*1019 mouvements à faire.
On divise ce nombre par le nombre de mouvements par jour :
1,8*1019 / 21600 = 8,5*1014 jours pour finir le jeu (pour la fin du monde).
4INFINFRC0007 Page 9
http://www.najah.com
NB : Dans d’autres versions du PVC, la notion de distance est remplacée par d'autres notions
comme le temps qu'il met ou l'argent qu'il dépense : dans tous les cas, on parle de coût.
Problématique :
Le problème du voyageur de commerce est dit "NP complet", dont les possibilités augmentent
exponentiellement avec le nombre de villes :
Si n est le nombre de villes, pour la seconde étape de son périple notre voyageur a N-1
possibilités, pour la troisième N-2, etc.
Il faut donc trouver un autre algorithme pour résoudre le problème, qui trouverait dans un
temps raisonnable une solution approchée.
Les algorithmes déterministes examinent toutes les possibilités ou, du moins, s'assurent de
ne pas écarter la meilleure solution.
Les algorithmes d'approximation se contentent de trouver une solution raisonnable en
explorant seulement une partie des possibilités. Lorsqu'ils trouvent la solution optimale, c'est
dans un temps beaucoup plus court qu'avec des algorithmes déterministes mais rien ne prouve
que c'est réellement la bonne solution. Pour des problèmes plus complexes (1000 villes ou
plus ), ils deviennent incapables de trouver la solution optimale mais sont intéressants pour
obtenir un premier résultat approché qui servira de base à des algorithmes déterministes.
4INFINFRC0007 Page 10
http://www.najah.com
Plusieurs recherches ont étés faites et se font encore, ces recherches ont aboutit à des
méthodes donnant de très bonnes approximations, citons à titre d'exemples :
Activité
Cherchez une solution récursive permettant d’afficher l’itinéraire que doit suivre un voyageur
de commerce pour visiter N villes.
Commencez par un nombre de villes réduit.
Analyse
- La recherche des distances entre les n villes ainsi que la distance totale est faite par la
procédure trajets.
- Les distances sont déterminées en fonction de la ville la plus proche, cette recherche est faite
par la procédure ville_plus_proche.
- Pour connaître la ville la plus proche, il faut calculer la distance entre deux villes. Cette
tâche est réalisée par la fonction distance.
- Pour calculer la distance entre deux villes il nous faut leurs coordonnées, c’est la procédure
saisie_ville qui saisit les coordonnées d’une ville ainsi que son nom.
- Nous avons N villes, la saisie de la liste des N villes est faite par la procédure saisie_liste.
- Pour commencer un itinéraire précis, en part d’une ville donnée, cette ville doit être présente
dans la liste et ses coordonnées sont uniques. Cette tâche est réalisée par la procédure
Saisie_ville_depart.
- La saisie du nombre N des villes à visiter se fera en même temps que la saisie de la liste des
villes, donc par la procédure saisie_liste.
4INFINFRC0007 Page 11
http://www.najah.com
4INFINFRC0007 Page 12
http://www.najah.com
Saisir les noms et les coordonnées de la liste des villes dans le tableau T.
C'est une itération de 1 à N, on commence par un appel de la procédure saisie_ville qui saisie
les coordonnées et les noms des villes,
Une ville doit exister une et une seule fois dans la liste donc une test de vérification de
l'unicité de cette ville est nécessaire.
Pour i de 1 à n Faire
Répéter
Proc saisie_ville (city)
Pour de 1 à i Faire
Si ((T[j].nom=city.nom) OU ((T[j].x=city.x) ET (Tt[j].y=city.y)))
Alors
Ecrire (" Nom ou emplacement déja saisie. ")
CestBon := Faux
Sinon CestBon:= Vrai
Fin Si
Fin Pour
Jusqu'à (CestBon)
Si le test est OK (C'est bon : variable CestBon reçoit Vrai) alors on affecte ces données au
tableau T.
T[i] := city
Fin Pour
Puisque la saisie des coordonnées et du nom d'une ville va servir aussi pour la ville de départ,
nous ferons appel deux fois à une procédure Saisie_ville pour éviter les redondances.
Proc saisie_ville (city)
Fin Saisie_liste
4INFINFRC0007 Page 13
http://www.najah.com
1) Répéter
Ecrire ("Combien de ville voulez vous visiter ? ")
Lire (N)
Jusqu'à (N > 0) ET (N < nbmaxville)
2) Pour i de 1 à N Faire
Répéter
Proc saisie_ville (city)
Pour j de 1 à i Faire
Si ((T[j].nom=city.nom) OU ((T[j].x=city.x) ET (T[j].y=city.y))) Alors
Ecrire ("Nom ou emplacement déja saisie. ")
CestBon Å Faux
Sinon CestBon Å Vrai
Fin Si
Fin Pour
Jusqu'à (CestBon )
T[i] := city
Fin Pour
3) Fin saisie_liste
4INFINFRC0007 Page 14
http://www.najah.com
Lire (v_depart.nom) ;
Pour i de 1 à N Faire
Si (v_depart.nom = T[i].nom) Alors
v_depart Å T[i]
placeville Å i
existe Å Vrai
Fin Si
Fin Pour
Si (existe = Faux) Alors Ecrire (" ville non existante ")
Jusqu'à (existe)
Fin saisie_ville_départ
Pour i de 1 à n Faire
Si (v_depart.nom = T[i].nom) Alors
v_depart Å T[i]
placeville Å i
existe Å Vrai
Fin Si
Fin Pour
4INFINFRC0007 Page 15
http://www.najah.com
- On cherche dans le tableau T, la ville la plus proche (son indice) à partir de place_ville et on
calcule la distance entre cette ville et la ville de départ. Cette tâche est réalisée par la
procédure ville_plus_proche.
- Le trajet entre la ville de départ et la ville la plus proche est maintenant connu, et puisque le
voyageur ne doit pas visité deux fois la même ville, on supprime du tableau la ville de départ,
on décrémente le nombre de ville de 1 et on suppose que la nouvelle ville de départ est la ville
trouvée. Cette tâche est faite par la procédure supprime_ville.
- On répète ce traitement jusqu'à ce qu'on arrive à un tableau contenant une seule ville. Ce qui
implique que toutes les villes ont étés visitées.
Tant Que ( N >1) Faire
T[placeville] Å T[N]
T[N] Å v_depart
4INFINFRC0007 Page 16
http://www.najah.com
Les deux points sont les deux villes v1 et v2 avec leurs coordonnées.
xx Å v1.x - v2.x
yy Å v1.y - v2.y
d Å racine_carrée ( carré (xx)+ carré (yy) )
distance Å d
Fin distance
4INFINFRC0007 Page 17
http://www.najah.com
Programme Pascal
4INFINFRC0007 Page 18
http://www.najah.com
PROGRAM voyageur ;
USES Crt ;
Const nbmaxville = 20 ;
Type
ville = Record
nom : String[16];
x, y : Real ;
End;
town = Array [1.. nbmaxville] of ville ; { town = ville en anglais}
VAR
T, T2 : town ;
N : integer ;
existe : Boolean ;
disttot, dist : Real ;
v_depart : ville;
Placeville : Integer ;
{************************************************************}
FUNCTION distance (v1,v2 : ville) : Real;
VAR
xx, yy, d : Real;
BEGIN
xx:=v1.x-v2.x ;
yy:=v1.y-v2.y ;
d:= sqrt (sqr(xx) + sqr(yy)) ;
distance := d ;
END;
{************************************************************}
PROCEDURE Saisie_ville_depart (VAR v_depart : ville; VAR palceville : Integer);
VAR i : Integer ;
existe : Boolean ;
BEGIN
Repeat
WriteLn ('Veuillez saisir le nom de la ville de départ ? ') ;
ReadLn (v_depart.nom) ;
For i:=1 To N Do
Begin
If (v_depart.nom = T[i].nom) Then
Begin
v_depart:= T[i] ;
placeville := i ;
existe := True;
End;
End;
If (existe = False) Then
WriteLn (' ville non existante ') ;
Until (existe);
END ;
4INFINFRC0007 Page 19
http://www.najah.com
{***********************************************************}
PROCEDURE saisie_ville (VAR city:ville);
BEGIN
WriteLn ('Entrer le nom de la ville : ') ; ReadLn (city.nom) ;
WriteLn ('Entrer l''abscisse de la ville : ') ; ReadLn (city.x);
WriteLn ('Entrer l''ordonnée de la ville: ');readln(city.y);
END;
{*******************************************************************}
PROCEDURE saisie_liste (VAR n : Integer ; VAR T : town ) ;
VAR
i, j : Integer ;
city : ville ;
cestbon : Boolean ;
BEGIN
Repeat
Writeln ('Combien de ville voulez vous visiter ? ') ;
ReadLn (N) ;
Until (N > 0) AND (N < nbmaxville) ;
For i:=1 To N Do
Begin
Repeat
saisie_ville (city);
For j:= 1 To i Do
Begin
If ((T[j].nom=city.nom) OR ((T[j].x=city.x) AND (T[j].y=city.y))) Then
Begin
Writeln ('Nom ou emplacement déja saisie. ');
CestBon := False ;
End
Else CestBon:= True;
End ;
Until (CestBon ) ;
T[i] := city;
End;
END;
{***************************************************************}
PROCEDURE Supprime_ville (VAR T : town ; city : ville) ;
VAR i, j : Integer;
BEGIN
For i:=1 To N Do
Begin
If (T[i].nom = city.nom) Then
Begin
N := N - 1;
For j:= i To N Do
4INFINFRC0007 Page 20
http://www.najah.com
T[j] := T [j+1];
End ;
End ;
END;
{********************************************************************}
PROCEDURE ville_plus_proche (T: town; VAR pproche : Integer; VAR dist : Real);
VAR i : Integer ;
BEGIN
Pproche := 1 ;
Dist := distance (T[1], T[N]);
For i:=2 To N -1 Do
Begin
If (distance (T[i], T[N]) < dist) Then
Begin
dist :=distance(T[i], T[N]);
pproche:= i ;
End;
End ;
END;
{********************************************************************}
PROCEDURE Trajet (v_depart : ville ; dist, disttot : Real ; Placeville : Integer);
BEGIN
WriteLn ('Premiere ville : ', v_depart.nom) ;
While (N >1) Do
Begin
T[placeville]:=T[N] ;
T[N] := v_depart ;
ville_plus_proche (t, placeville, dist) ;
disttot := disttot + dist ;
supprime_ville (T,v_depart) ;
v_depart := T[placeville] ;
WriteLn ('ville suivante : ', v_depart.nom);
WriteLn ('Distance entre les deux dernière ville : ', dist) ;
End ;
WriteLn ('Distance totale : ', disttot) ;
END;
{ ************************** PP *********************************}
BEGIN
ClrScr ;
Disttot := 0;
Existe := false;
Saisie_liste (N,T) ;
Saisie_ville_depart (v_depart, placeville) ;
4INFINFRC0007 Page 21
http://www.najah.com
Dans le cas général, le problème des dames consiste à placer N dames sur un échiquier de
taille N x N toujours de telle sorte qu'aucune dame ne soit en prise : il ne faut donc pas plus
d'une dame par ligne, par colonne et par diagonale.
Les solutions
Le problème des huit dames a 92 solutions distinctes, on peut représenter 12 solutions
distinctes, les autres sont des transformations telles que des rotations ou des réflexions.
4INFINFRC0007 Page 22
http://www.najah.com
4INFINFRC0007 Page 23
http://www.najah.com
1 1 2 0 3 0
4 2 5 10 6 4
7 40 8 92 9 352
10 724 11 2680 12 14200
13 73712 14 365596 15 2279184
Le problème des huit dames parait simple mais il est un peu difficile. Pour cette raison, il est
souvent employé comme support de mise en œuvre de différentes techniques de
programmation, dont nous avons parlés au niveau du problème du voyageur de commerce. Ce
sont des approches non traditionnelles de la programmation telles que la programmation par
contraintes, la programmation logique ou les algorithmes génétiques. Ces approches ne
seront pas abordées car ils ne sont pas au niveau de notre programme.
C'est un problème qui peut être résolu avec un algorithme récursif, en exprimant qu'une
solution pour N dames peut être obtenue, par récurrence, à partir d'une solution quelconque du
problème des (N-1) dames par L'ajout d'une dame. La récurrence commence avec la solution
du problème de 0 dame qui repose sur un échiquier vide.
Activité
Proposez des modules récursifs d’un programme permettant d’afficher les positions et le
nombre de solutions pour le problème des 8 dames.
Analyse du problème
a) Analyse du programme principal
Résultat :
Afficher les différentes solutions de l'emplacement de 8 dames sur un échiquier de 8x8
Afficher le nombre de ces solutions.
Traitement : On considère un tableau T de 8 colonnes initialisé au départ à zéro (Procédure
init_tab).
On appelle une procédure place_dame pour placer une dame dans chacune des positions libres
de l'échiquier, la position trouvée sera notée dans la première case du tableau T.
Le principe est le suivant : il est clair qu'il y aura une dame et une seule par colonne et par
ligne, donc dans le tableau T l'indice indique la ligne de l'échiquier et le contenu de la case i
(T[i]), indique la colonne de l'échiquier.
Le test suivant évite de mettre une dame sur la même ligne ou sur la même colonne
i représente la ligne et j la colonne.
Si ((T[ j ] = i ) OU (ABS(T[ j ] - i ) = ABS (j - nDames))) ALORS
Arrêter le traitement car deux dames se menacent (se trouvent sur la même ligne, la même
colonne ou la même diagonale) et passer à un autre positionnement.
S'il n'y a pas de menace, on garde cette position et on appelle le même traitement pour la
dame suivante. Donc ce traitement est récursif.
On arrête lorsqu'on place la huitième dame à sa place.
On affiche l'échiquier on représentant par "1" la position de la dame et par "0" les cases vides.
Cette tâche est réalisée par la procédure affiche.
4INFINFRC0007 Page 24
http://www.najah.com
Données : Dans cette première activité, le nombre de dames est une constante égale à 8.
nbd = 8
Dans la variable nDames on cumule le nombre de dames placées sur l'échiquier
Fin Huit Dames
4INFINFRC0007 Page 26
http://www.najah.com
Alors arrêter le traitement car deux dames se menacent (se trouvent sur la même ligne, la
même colonne ou la même diagonale) et passer à la recherche d'autres positionnements. Pour
ceci, nous avons utilisé la procédure prédéfinie "Continue" (présente dans les versions 5, 6
et 7 de Turbo Pascal), qui provoque le passage du contrôle de l'exécution à l'itération suivante.
Un branchement inconditionnel (Aller à, en Pascal GoTo) permet le saut ou le branchement
inconditionnel vers l'étiquette ou l'identificateur de la procédure "Continue" que nous
avons appelé "suivant".
suivant : continue
S'il n'y a pas de menace, on sauvegarde cette position dans le tableau T, on appelle le même
traitement pour la dame suivante. Donc ce traitement est récursif.
On arrête lorsqu'on place la huitième dame à sa place.
T[nDames] Å i
Proc place_dame (T, nDames +1)
Quand la huitième dame est placée à la bonne case, on appelle la procédure affiche pour
afficher les 8 dames placées sur l'échiquier puis on ajoute 1 au nombre total de solutions
trouvées.
Si (nDames = nbd +1) Alors
Proc Affiche (T, nbd)
solution Å solution + 1
Fin Si
Fin Analyse
suivant : continue
Fin pour
3) Fin place_dame
4INFINFRC0007 Page 27
http://www.najah.com
Programme Pascal
PROGRAM huit_dames ;
Uses Crt ;
Const nbd = 8 ;
Type Tab = Array [1..nbd] of Intege r;
Var
T: Tab;
solution :Integer ;
{********************************************************************}
PROCEDURE init (VAR T : Tab; nbd: Integer );
VAR i : Integer ;
BEGIN
For i:=1 To nbd Do T[i]:= 0;
END ;
{********************************************************************}
PROCEDURE affiche (T: Tab ; nbd : Integer);
VAR i, j : Integer ;
BEGIN
Writeln (' ------- SOLUTION : ', solution +1, ' ---------------');
For i := 1 To nbd Do
Begin
For j:=1 To nbd Do
if (j = T[i]) Then Write ('1') else Write ('0');
WriteLn;
End;
WriteLn ; ReadLn ;
END ;
{********************************************************************}
PROCEDURE place_dame (T : Tab; nDames : Integer);
Label suivant ;
VAR i, j : Integer ;
BEGIN
If (nDames = nbd+1) Then
Begin
Affiche (T, nbd) ;
solution := solution + 1 ;
End ;
T[nDames]:= i ;
place_dame (T, ndames +1);
suivant : continue;
End;
END;
4INFINFRC0007 Page 29