Está en la página 1de 136

D houihri Alaa

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 :

Tableau de déclaration des nouveaux types


Type
Nom_type = Enregistrement
champ 1 : Type 1
-- --
champ n : Type n
Fin Nom_Type

Puis la déclaration des objets (variables) utilisant ce type

Tableau de déclaration des objets


Objet Type / Nature Rôle
identificateur_objet Nom_type Enregistrement pour …

En Pascal :

TYPE Nom_type = Record


champ_1 : type_1 ;
- - --
champ_n : type_n ;
End;

VAR
identificateur_objet : Nom_type ;

III/ Utilisation
4INFINFRC0001  Page 1 
http://www.najah.com 

Utilisation pour une action d'affectation


L'affectation de valeurs aux différents champs d'une variable de type enregistrement se
fait par une opération de type :

En algorithmique En Pascal
variable.champ ← valeur variable.champ := valeur ;

Exemple :

En algorithmique :

Tableau de déclaration des nouveaux types :


Type
Fiche = enregistrement
nom, prénom : Chaîne
sexe : Caractère
numéro : Entier non signé
moyenne : Réel
num_cin : Entier long
Fin Fiche

Tableau de déclaration des objets :


Objet Type / Nature Rôle
élève Fiche Enregistrement pour une fiche d'un étudiant

Affectation de valeurs à cette variable :

é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.

TYPE Fiche = Record


nom, prenom : String ;
sexe : Char ;

4INFINFRC0001  Page 2 
http://www.najah.com 

numero : Byte ;
moyenne : Real ;
num_cin : LongInt ;
End ;

Déclaration de la variable élève :

VAR
eleve : Fiche ;

Affectation des valeurs à cette variable :

eleve.nom := 'Swidi' ;
eleve.prenom := 'Basma' ;
eleve.sexe := 'F' ;
eleve.numero := 18 ;
eleve.moyenne := 13.25 ;
eleve.num_cin := 12345678 ;

Utilisation pour une action de lecture

Au niveau de l'analyse Au niveau de l'algorithme Au niveau du Pascal


variable.champ = Donnée Lire (variable.champ) ReadLn (variable.champ);

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) ;

Utilisation pour une action d'écriture

Au niveau de l'analyse et de l'algorithme Au niveau du Pascal


Ecrire (variable.champ) Write (variable.champ);

Exemple :

4INFINFRC0001  Page 3 
http://www.najah.com 

Au niveau de l'analyse et de l'algorithme :


Ecrire ("Nom : ", élève.nom)

Au niveau du Pascal :
WriteLn ('Nom : ', eleve.nom) ;

Structure Avec .. Faire


Pour simplifier l'écriture et éviter l'utilisation répétée des champs et de la notation avec le
point (variable.champ), on peut utiliser l'instruction Avec .. Faire (With .. Do).
Cette structure s'utilise aussi bien avec une opération d'affectation, de lecture ou d'écriture.

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 :

Avec élève Faire


{Affectation}
nom ← "Swidi"

{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' ;

Write ('Entrer le sexe de l''élève : ') ; ReadLn (sexe) ;

WriteLn ('Moyenne : ', moyenne) ;


End;

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 :

Tableau de déclaration des nouveaux types :


Déclaration de la variable T utilisant les enregistrements des élèves :

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 :

Objet Type / Nature Rôle


T Tab Tableau d'enregistrements pour les fiches des élèves

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 :

Analyse du programme principal

Résultat : Affichage d'une fiche


- Traitement : - Une fiche peut être représentée par une structure d'enregistrement
comportant 4 champs (le nom, le numéro, le numéro de téléphone et le code d'assurance).
- L'affichage des différents champs sera la tâche de la procédure Afficher.

4INFINFRC0001  Page 5 
http://www.najah.com 

- La saisie des différents champs se fera par la procédure Saisir.


Fin Analyse

Algorithme du programme principal


0) Début Fiche
1) Saisir (Patient)
2) Afficher (Patient)
3) Fin Fiche

Tableau de déclaration des nouveaux types

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

Tableau de déclaration des objets globaux :

Nom Type / Nature Rôle


Patient Personne Enregistrement pour une fiche personne
Saisir Procédure Saisie des champs
Afficher Procédure Affichage des champs

Analyse de la procédure saisir

Résultat : Saisir les champs


Traitement :
La saisie des différents champs de l'enregistrement se fera par des opérations de lecture avec
l'utilisation de la structure Avec .. Faire, sur la variable Patient.
Patient : représente la variable de l'enregistrement.
Fin Analyse

Algorithme de la procédure Saisir

0) Procédure Saisir (VAR Patient : Personne)


1) Avec Patient Faire
Ecrire ("Entrer le nom de la personne : ") ; Lire (nom)
Ecrire ("Entrer son numéro : ") ; Lire (numéro)
Ecrire ("Entrer son numéro de téléphone : ") ; Lire (tel)
Ecrire ("Entrer le code d'assurance : ") ; Lire (code)

4INFINFRC0001  Page 6 
http://www.najah.com 

Fin Avec
2) Fin Saisir

Analyse de la procédure Afficher

Résultat : Afficher les champs


Traitement :
L'affichage des différents champs de l'enregistrement se fera par des opérations d'écriture
avec l'utilisation de la structure Avec .. Faire, sur la variable Patient.
Fin Analyse.
Algorithme de la procédure Afficher
0) Procédure Afficher (Patient : Personne)
1) Avec Patient Faire
Ecrire ("Nom : ", nom)
Ecrire ("numéro : ", numéro)
Ecrire ("Numéro de téléphone : ", tel)
Ecrire ("Code assurance : ", code)
Fin Avec
2) Fin Afficher

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 :

Analyse de la fonction Factorielle


Résultat : Factorielle
Traitement :
On initialise F à 1 (F ← 1), car Factorielle de zéro = 1 et Factorielle de 1 = 1
On termine le calcule, par une itération complète de 2 à N
Pour i de 2 à n Faire
F←F*i
Fin Analyse

Algorithme de la fonction Factorielle


0) Fonction Factorielle (n : Entier) : Entier Long
1) F ← 1
2) Pour i de 2 à n Faire
F←F*i
Fin Pour
3) Factorielle ← F
4) Fin Factorielle

Tableau de codification des objets locaux


Objets Type/Nature Rôle
F Entier Long La factorielle de n
i Entier Compteur

NB : Ce calcul a été obtenu à partir d'une boucle Pour … Faire. C'est un traitement itératif.

Reprenons, pas à pas, le calcul de la factorielle.

4INFINFRC0002  Page 1 
http://www.najah.com 

n ! = n * (n-1) * (n-2) * (n-3) * … * 1


Avec 0 ! = 1

On peut mettre en évidence les différentes étapes :


Factorielle (n) = n * (n-1) * (n-2) * (n-3) * … * 1
et factorielle (0) = 1

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).

Ce procédé, un module qui fait appel à lui-même, s’appelle Traitement Récursif

On peut donc écrire une fonction récursive de calcul de la factorielle d'un entier N.

Algorithme de la fonction Factorielle : solution récursive


0) Fonction Factorielle (n : Entier) : Entier Long
1) Si (n = 0) Alors Factorielle ← 1 {test de sortie}
Sinon Factorielle ← n * Factorielle (n-1) {appel récursif}
Fin Si
2) Fin Factorielle

Programme Pascal utilisant la fonction récursive de calcul de la factorielle


PROGRAM Fact_rec;
Uses Crt;
Var n : Integer;

{----------------------------------------------------------------}
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.

Un programme récursif doit :


* Avoir au moins un point d'arrêt (une condition de sortie) pour ne pas être dans une boucle
infinie.
* Avoir un ou plusieurs traitements représentés par des appels récursifs.

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

b) Algorithme du programme principal


0) Début Prg_puissance
1) Ecrire ("Donner un réel : ") , Lire (x)
2) Ecrire ("Donner en entier n : ") , Lire (n)
3) Ecrire (x, " à la puissance ", n, " = ", Fn Puissance (x, n))
4) Fin Prg_puissance

4INFINFRC0002  Page 4 
http://www.najah.com 

Tableau de codification des objets globaux


Objets Type/Nature Rôle
x Réel Donnée
n Entier L’exposant
Puissance Fonction Permet de déterminer la valeur xn

Analyse de la fonction Puissance


Résultat : Puissance
Traitement :
Si (n = 0) alors Puissance ← 1 {condition de sortie}
Sinon Si (n < 0) alors Puissance ← 1 / Fn Puissance (a, -n)
Sinon Puissance ← a * Fn Puissance (a, n-1)
Fin Analyse

Algorithme récursif de la fonction Puissance


0) Fonction Puissance (x : Réel ; n : Entier) : Réel
1) Si n = 0 Alors Puissance ← 1
Sinon Si n < 0 Alors Puissance ← 1 / Fn Puissance (a, -n)
Sinon Puissance ← a * Fn Puissance (a, n-1)
Finsi
2) Fin Puissance

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

Algorithme du programme principal Recherche

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 

Tableau de déclaration des objets globaux


Objets Type/Nature Rôle
T Tab Tableau d'entiers
n Entier Taille du tableau
V Entier Valeur recherchée
Dicho_Rec Fonction Recherche récursive et dichotomique de V dans T
Saisir Procédure Permet de saisir la taille du tableau
Remplir_Trier Procédure Permet de remplir le tableau trié
existe Boolean Reçoit le résultat de la fonction Dicho_Rec

Tableau de déclaration des nouveaux types


Type
Tab = Tableau de 20 entiers

4INFINFRC0002  Page 7 
http://www.najah.com 

b/ Analyse de la fonction Dicho_Rec


Résultat : Dicho_Rec
Traitement :
- le résultat final est un Booléen qui indique que V est trouvée ou non.
- Une première condition de sortie est que V = T[milieu] alors V existe dans T.
Une seconde est que V n'existe pas dans le tableau.

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

Algorithme récursif de la fonction Dicho_Rec


0) Fonction Dicho_Rec (début, fin, V : Entier ; T : Tab ) : Booléen
1) milieu ← (début + fin) Div 2
2) Si V = T[milieu] Alors Dicho_Rec ← Vrai
Sinon Si (V < T[milieu]) ET (début < milieu)
Alors Dicho_Rec ← Fn Dicho_Rec (début, milieu-1, V, T)
Sinon Si (V > T[milieu]) ET (fin > milieu)
Alors Dicho_Rec ← Fn Dicho_Rec (milieu +1, fin, V, T)
Sinon Dicho_Rec ← Faux
Fin Si
3) Fin Dicho_Rec

Tableau de déclaration des objets locaux


Objets Type/Nature Rôle
milieu Entier Indice de l’élément du milieu de la partie dans laquelle
s’effectue la recherche.

Analyse de la procédure Saisie


Résultat : Saisie de la taille du tableau
Traitement :
Répéter
Lire (n)
Jusqu'à n Dans [4 .. 20]
Fin Analyse

Algorithme de la procédure Saisie


0) Procédure Saisie (VAR n : Entier )
1) Répéter
Ecrire ("N = ");
Lire (n)
Jusqu'à n Dans [4 .. 20]
4INFINFRC0002  Page 8 
http://www.najah.com 

2) Fin Saisie

Analyse de la procédure Remplir_Trier


Résultat : Tableau trié
Traitement :
Lire T[1]
Lire T[2] et n'accepter la que une valeur supérieure ou égal T[1]
Répéter ce traitement pour les n valeurs du tableau.
Fin Analyse

Algorithme de la procédure Remplir_Trier


0) Procédure Remplir_Trier (n : Entier ; VAR T : TAB)
1) Ecrire ("T[1] = ")
2) Lire (T[1])
3) Pour i de 2 à n Faire
Répéter
Ecrire ("T[", i, "] = ")
Lire (T[i])
Jusqu'à (T[i] ≥ T[i-1])
4) Fin Remplir_Trier

Tableau de codification des objets locaux


Objets Type/Nature Rôle
i Entier Compteur

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 ALGORITHMES DE TRI


I/ Introduction
Selon le dictionnaire
"trier" signifie «répartir des objets suivant certains critères».

En informatique le "tri" un processus de classement d'une suite d'éléments dans un ordre


donné.

Il existe deux catégories de tris :


- Les tris internes : Méthodes destinées à des masses de données limitées, stockées dans une
structure de données se trouvant dans la mémoire centrale (Exemple : tableaux).

- 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.

I/ Tri par sélection


Activité
Ecrire un programme nommé Tri_Sélection, qui remplit de façon aléatoire un tableau T par N
Réels.
Affiche l'état actuel du tableau puis celui du tableau trié par ordre croissant en utilisant la
méthode du tri par sélection.
N est entier compris entre 4 et 25.

*-*-*-*-*-*-*-*-*-*-*

Analyse du programme Tri_Sélection


Résultat = Tableau trié
Traitement :
- Une procédure Affiche_Tab, permet d'afficher le contenu du tableau. Elle va servir pour
l'affichage du tableau non trié puis pour le tableau trié.
- Une procédure Tri_Sélect, permet le tri par sélection du tableau.
- Une procédure Saisie, permet la saisie et le test de N.
- Une procédure Remplir_Hasard, permet de remplir de façon aléatoire (au hasard) le tableau.
Fin Analyse

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 

5) Proc Tri_Select (T, N)


6 ) Ecrire ("Tableau trié ")

7) Proc Affiche_Tab (T, N)


8) Fin Tri_Sélection

Tableau de déclaration des objets globaux


Objet Type / Nature Rôle
N Entier Nombre d'éléments du tableau
T Tab Tableau des réels
Saisie Procédure Saisie et test de N
Remplir_Hasard Procédure Remplit au hasard le tableau T
Affiche_Tab Procédure Affiche le contenu du tableau
Tri_Sélect Procédure Tri le tableau par sélection

Tableau de déclaration des nouveaux types


Types
TAB = Tableau de 25 réels

Analyse de la procédure Saisie


Résultat = Saisie et test de N
Traitement
Répéter
N = Donnée ("Entrer la taille du tableau : ")
Jusqu'à (4 ≤ N ≤ 25)
Fin Saisie

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

Analyse de la procédure Remplir_Hasard


Résultat = Remplir le tableau T par des réel pris au hasard
Traitement :
- La fonction prédéfinie Hasard (N ) en Pascal Random (N), renvoie un entier aléatoire
compris entre 0 et N-1.
Si N est omis, la fonction renvoie un réel compris entre 0 et 9.999….
Donc pour obtenir un réel, par exemple entre 0 et 100, on multiplie le résultat de Hasard par
100.

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

Tableau de déclaration des objets locaux


Objet Type / Nature Rôle
i Entier Compteur

Analyse de la procédure Tri_Select


Résultat = Tableau T trié
Traitement :
Lorsque le tri est par ordre croissant, la méthode est parfois appelée tri par recherche de
minima, car on commence par le plus petit élément.

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 méthode de tri par sélection est donc la suivante :


1- On cherche le plus petit élément en parcourant tout le tableau et on le permute avec celui
occupant la première case.
2- La plus petite valeur occupe définitivement sa place qui est la première case. On cherche
maintenant la plus petite valeur dans le tableau T mais on commençant à partir du deuxième
élément. Si elle existe elle sera permuter avec c'elle de la deuxième case.
3- On répète le même traitement à partie de la troisième case et ainsi de suite jusqu'à la case
N-1.

- 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

Tableau de déclaration des objets locaux


Objet Type / Nature Rôle
i Entier Compteur
Pos_Min Entier Position de la valeur minimale
Cherche_Min Fonction Retourne la position de la valeur minimale
Permute Procédure Permute le contenu de deux variables

Analyse de la fonction Cherche_Min


Résultat = Cherche_Min
Traitement :
- On suppose que l'élément de départ est le plus petit donc sa position est son indice.
Min Å T[départ]
Indice Å Départ
- On parcourt le tableau à partir de la position départ + 1 jusqu'à N à la recherche d'un élément
plus petit, s'il existe, on mémorise sa valeur et sa position.
Pour j de départ + 1 à N Faire
Si T[j] < Min Alors Min Å T[j]
indice Å j
Fin Si
Fin Pour
- Le résultat est la valeur indice
Cherche_Min Å indice
Fin Analyse

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 

Tableau de déclaration des objets locaux


Objet Type / Nature Rôle
j Entier Compteur
Min Réel Valeur minimale
indice Entier Position de la valeur minimale

Analyse de la procédure Permute


Résultat = Permuter le contenu de deux variables

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

Tableau de déclaration des objets locaux


Objet Type / Nature Rôle
temp Réel Variable temporaire pour la permutation

Analyse de la procédure Affiche_Tab


Résultat = Afficher le contenu du tableau T.
Traitement :
- Parcourir le tableau et afficher tous ses éléments à l'aide d'une itération complète.
Pour i de 1 à N Faire
Ecrite (T[i])
Fin Pour
Fin Analyse

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

Tableau de déclaration des objets locaux


Objet Type / Nature Rôle
i Entier Compteur

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 

WriteLn ('Tableau non trié ');


Affiche_Tab (T, N) ;

Tri_Select (T, N) ;
WriteLn ('Tableau trié " );
Affiche_Tab (T, N) ;
END.

II/ Tri à bulles


Activité
Ecrire un programme nommé Tri_Bulles, qui permet le tri d'un tableau T de N réels, par la
méthode du tri à bulles.
Ce programme affiche le contenu du tableau non trié puis le contenu du tableau trié par ordre
décroissant.
N est entier compris entre 4 et 25.
Le tableau est remplit de façon aléatoire un tableau T par N Réels.

*-*-*-*-*-*-*-*-*-*-*

Analyse du programme Tri_Bulles


Résultat = Tableau trié
Traitement :
- Les procédures de saisie de N, du remplissage du tableau et de l'affichage sont les mêmes
que ceux de l'activité précédente.
- Une procédure nommée Bulles, permet le tri du tableau par une des méthodes du tri à bulles.
Fin Analyse

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

Analyse de la procédure Bulles


4INFINFRC0003  Page 8 
http://www.najah.com 

Il existe plusieurs méthodes du tri à bulles, en voici une :


L'algorithme du tri à bulles (bubble sort en anglais) consiste à comparer les différentes valeurs
adjacentes du tableau T, et à les permuter s'ils ne sont pas dans le bon ordre.
Pour i de 1 à N-1 Faire
Si (T[i] > T[i+1]) Alors Proc Permuter (T[i], T[i+1])
Si au moins une permutation est faite, une variable booléenne (échange) reçoit par exemple
Vrai, si elle a été initialisée au départ à Faux
échange Å Vrai
Le tri se termine quand il n'y a plus de permutations (échange = faux) sinon on répète le
même traitement.
Jusqu'à échange = Faux
Fin Analyse

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

Tableau de déclaration des objets locaux


Objet Type / Nature Rôle
i Entier Compteur
échange Booléen Drapeau de test
Permuter Procédure Permute le contenu de deux variables

Programme complet en Pascal


PROGRAM Tri_Bulles ;
USES Crt ;

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.

III/ Tri par insertion


Activité
Ecrire un programme nommé Tri_Insertion, qui permet le tri d'un tableau T de N réels, par la
méthode du tri par insertion.
Ce programme affiche le contenu du tableau non trié puis le contenu du tableau trié par ordre
décroissant.
N est entier compris entre 4 et 25.
Le tableau est remplit de façon aléatoire un tableau T par N Réels.
*-*-*-*-*-*-*-*-*-*-*
Analyse du programme Tri_Insertion
Résultat = Tableau trié
Traitement :
- Les procédures de saisie de N, du remplissage du tableau et de l'affichage sont les mêmes
que ceux de l'activité précédente.
- Une procédure nommée T_Insertion, permet le tri du tableau par la méthode du tri par
insertion.
Fin Analyse

Algorithme
0) Début Tri_Insertion
1) Proc Saisie (N)

4INFINFRC0003  Page 11 
http://www.najah.com 

2) Proc Remplir_Hasard (T, N)


3) Ecrire ("Tableau non trié ")
4) Proc Affiche_Tab (T, N)
5) Proc T_Insertion (T, N)
6 ) Ecrire ("Tableau trié ")
7) Proc Affiche_Tab (T, N)
8) Fin Tri_Insertion

Analyse de la procédure T_Insertion


Le principe du tri par insertion, est identique au classement qu'un joueur de "rami" ou de
"belote" utilise pour ranger ses cartes. Il tire une carte et la met à sa place parmi les autres
cartes déjà rangées puis il recommence avec la carte suivante jusqu'au rangement de toutes les
certes dans sa main.

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.

Le processus d'insertion consiste à :


- Utiliser une variable intermédiaire tmp pour conserver la valeur à insérer,
- Déplacer les éléments T[i-1], T[i-2], ... vers la droite tant que leur valeur est supérieure à
celle de tmp.
- Affecter alors à l'emplacement laissé libre par ce décalage la valeur de tmp.
Tmp Å T[i]
jÅi
Proc Décaler (T, j, Tmp)
T[j] Å Tmp
Fin Analyse

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

Tableau de déclaration des objets locaux


Objet Type / Nature Rôle
i Entier Compteur

4INFINFRC0003  Page 12 
http://www.najah.com 

Tmp Réel Variable intermédiaire


j Entier Position d’insertion
Décaler Procédure Permettant de décaler des éléments d’un
tableau d’un certain nombre de positions

Analyse de la procédure Décaler


Résultat : Décaler à droite les éléments du tableau T d'indice début à l’indice fin
Traitement :
Il s'agit d'un traitement répétitif à condition d'arrêt réalisant le décalage :
Tant Que T[p -1] > Temporaire Faire
T[p] Å T[p-1]
p Å p -1
Fin Tant Que
- L'action de décalage est une simple affectation : T[p]Å T[p-1]
Puis La décrémentation de 1 de la variable p
Fin analyse

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

Programme complet en Pascal


PROGRAM Tri_Insertion ;
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 : ') ;

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 Decaler (VAR T : Vect; VAR p : Integer ; temporaire : Integer) ;


BEGIN
While T[p -1] > Temporaire Do
Begin
T[p] := T[p-1] ;
p := p -1 ;
End ;
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.

IV/ Tri Shell


En analysant l'algorithme du tri par insertion, nous pouvons remarquer qu'il fait n*(n-
1) comparaisons et décalages.
Il est toutefois évident que si le vecteur est initialement presque trié dans le bon ordre, le
nombre d'opérations sera beaucoup plus réduit.
Si la méthode de tri par insertion est efficace quand la liste est à peu près triée, elle est
inefficace en moyenne car elle ne change les valeurs que d'une position par instruction.
En effet, cette méthode traite un à un les éléments de la liste à trier et réalise un décalage des
éléments précédents jusqu'à avoir la position d'insertion de l'élément en cours.

Principe du tri Shell


Donald L. Shell proposa, en 1959, une variante du tri par insertion. Ce tri consiste à
trier séparément des sous tableaux du tableau initial, formés par les éléments répartis en un
nombre P calculé d'éléments.

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.

Au dernier stade, P0 est égal à 1 (retour au tri par insertion normal).


Nous déterminerons le pas maximal par récurrence en inversant la relation donnée ci-dessus :
Pk + 1 = 3 * Pk + 1

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.

*-*-*-*-*-*-*-*-*-*-*

Analyse du programme Tri_Shell


Résultat = Tableau trié
Traitement :
- Les procédures de saisie de N, du remplissage du tableau et de l'affichage sont les mêmes
que ceux des activités de tri précédentes.
- Une procédure nommée Shell, permet le tri du tableau par la méthode du tri Shell.
Fin Analyse

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

Analyse de la procédure Shell


Résultat = Tableau T trié
Traitement : C’est trier séparément des sous tableaux du tableau initial dont les éléments
sont distants de P cases par la méthode du tri par insertion.

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.

Tri par insertion normal Tri Shell


0) Procédure Tri_insertion (N: Entier; VAR 0) Procédure Shell (N : entier; VAR T :
T : Vect) Vect)
1) PÅ 1
Tant Que (P< N) Faire
P Å(3* P +1)
Fin Tant Que
2) Tant Que (P ≠1) Faire
P Å P DIV 3
1) Pour c de 2 à N Faire Pour c de P + 1 à N Faire
Si (T[c] < T[c-1]) Alors Si (T[c] < T[c-p]) Alors
Tmp Å T[c] Tmp Å T[c]
pos Å c pos Å c
Tant que (pos >1) ET (T[pos-1]> tmp) Tant Que (pos > P-1) et (T[pos-P]>
Faire tmp) Faire
T[pos]Å T[pos-1] T[pos]Å T[pos-P]
pos Å pos-1 posÅpos-P
Fin Tant que Fin Tant que
T[pos]Å Tmp T[pos]Å Tmp
Fin Si Fin Si
Fin Pour Fin Pour
2) Fin Tri_insertion Fin Tant Que
3) Fin Shell

4INFINFRC0003  Page 17 
http://www.najah.com 

Programme complet en Pascal


PROGRAM Tri_Shell ;
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 ;

{----------------------------------------------------------------------------------------}
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 ;

While (P < > 1) Do


Begin
P := P DIV 3 ;
For c := P + 1 To N Do
Begin
If (T[c] < T[c-p]) Then
Begin
Tmp := T[c] ;
pos := c ;
While (pos > P-1) AND (T[pos-P]> tmp) Do
Begin
T[pos] := T[pos-P] ;
pos := pos-P ;
End ; {End While }
T[pos] := Tmp ;
End ; {End If }
End ; {End For}
End ; {End While }
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.

V/ Tri par fusion

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

On peut diviser ce tableau en deux sous tableaux d'entiers T1 et T2 de longueurs respectives 7


et 8.

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

Triés par ordre croissant les deux sous tableaux T1 et T2

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 

- se pointer à l'élément n°2 de T


- Remarquez que nous sommes toujours à la première position de T1.

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.

*-*-*-*-*-*-*-*-*-*-*

Analyse du programme Tri_Fus1

4INFINFRC0003  Page 21 
http://www.najah.com 

Résultat = Tableau trié


Traitement :
- Les procédures de saisie de N, du remplissage du tableau et de l'affichage sont les mêmes
que ceux des activités de tri précédentes.
- Une procédure nommée Fus, permet le tri du tableau par la méthode décrite.
Fin Analyse

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

Analyse de la procédure Fus


Résultat = Tableau T trié
Traitement :
- Fusionner deux sous tableaux triés dans le tableau T, c'est le rôle de la procédure Fusionner.
- Trier successivement les deux sous tableaux, c'est le rôle de la procédure Trier.
- Diviser le tableau T en deux sous tableaux, c'est le rôle de la procédure Diviser.
Fin Analyse
Algorithme
0) Procédure Fus (VAR T : Vect; N : Entier)
1) Proc Diviser (T, N, T1, T2, N1, N2)
2) Proc Trier (T1, N1)
3) Proc Trier (T2, N2)
3) Proc Fusionner (T, N, T1, T2, N1, N2)
4) Fin Fus

Tableau de déclaration des objets locaux


Objet Type / Nature Rôle
Diviser Procédure Diviser le tableau T en deux sous tableaux
Trier Procédure Trier un tableau
Fusionner Procédure Fusionner deux sous tableaux triés

Analyse de la procédure Diviser


Résultat = Diviser le tableau T en 2 sous tableaux
Traitement :
- Calculer les tailles des sous tableaux
4INFINFRC0003  Page 22 
http://www.najah.com 

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

Tableau de déclaration des objets locaux


Objet Type / Nature Rôle
i Entier Compteur

Analyse de la procédure Trier


Résultat = Tableau trié
Traitement :
- Pour i de 1 à taille-1 Faire
Pour j de i+1 à taille Faire
Si Tx[i] > Tx[j] Alors aux Å Tx[i]
Tx[i] Å Tx[j]
Tx[j] Å aux
Fin Si
Fin Pour
Fin Analyse

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 

Pour j de i+1 à taille Faire


Si Tx[i] > Tx[j] Alors aux Å Tx[i]
Tx[i] Å Tx[j]
Tx[j] Å aux
Fin Si
Fin Pour
2) Fin Trier

Tableau de déclaration des objets locaux


Objet Type / Nature Rôle
i, j Entier Compteurs
aux Réel Variable auxiliaire

Analyse de la procédure Fusionner


Résultat = Trier en fusionnant les deux tableaux T1 et T2
Traitement :
- Ranger les éléments des tableaux T1 et T2 jusqu'à la fin de l'un des tableaux T1 ou T2.
cÅ0
c1 Å 1
c2 Å 1
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)

- 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)

5) Si (c1 > N1) Alors


Pour i de c2 à N2 Faire
T[c] Å T2[i]
Inc (c, 1)
Fin Pour
Sinon
Pour i de c1 à N1 Faire
T[c] Å T1[i]
Inc (c, 1)
Fin Pour
Fin Si
6) Fin Fusionner

Tableau de déclaration des objets locaux


Objet Type / Nature Rôle
c, c1, c2 Entier Compteurs

Programme complet en Pascal


PROGRAM Tri_Fusion_Simple ;
USES Crt ;

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 ;

{---- fusionner t[debut..milieu] et t[milieu +1..fi] ---------}


PROCEDURE fusion (VAR T : Tab ; debut, milieu, fin: Integer);
VAR
aux : Tab;
i, j, k, l, taille : Integer;
BEGIN
i := debut;
j := milieu+1;
taille := fin - debut +1;
For k:=1 To taille Do
Begin
If ((j > fin) OR (I < = milieu) AND (t[i] < t[j]))
Then Begin
aux[k] := t[i] ;
i := i +1;
End Else
Begin
aux[k] := t[j] ;
j := j +1;
End;
End;

{Recopier aux dans T}


l := 1;
For k := debut To fin Do
Begin
t[k] := aux[l];
l := l +1;
End;
END;

PROCEDURE tri_fusion (VAR T : Tab ; N : Integer);


VAR
debut, fin, i, milieu : Integer;
BEGIN
i := 1;
While (i <n) Do
Begin
debut := 1;
fin := debut + i + i-1; {Le pas}

4INFINFRC0003  Page 29 
http://www.najah.com 

While (debut + i-1 <= N) Do


Begin
fin := (fin + debut) - 1;
If (fin > N) Then fin := N;
Fusion (t, debut, debut + i-1, fin);
debut := debut + i + i;
End;
I := i+1;
End;
END;

{----------------------------------------------------------------------------------------}
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.

L'ordre est le nombre de traitements précédents dont dépend le résultat.

Un algorithme récurrent d’ordre p est un algorithme donnant un résultat dépendant des p


résultats précédents. p peut être 1,2,3, etc.

II/ Exemples d'algorithmes récurrents


II-1 Calcul de somme
Activité
1/ Ecrire une analyse et un algorithme de la procédure Somme_Matrice, qui calcule la somme
des éléments d’une matrice carrée d’entiers comportant n lignes et n colonnes
(4 ≤ n ≤ 20).
2/ Ce traitement est-il récurent ?
Dans l’affirmative donnez son 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.

Analyse de la fonction Somme_Matrice


Résultat : SOMME_MAT
Traitement : Pour calculer la somme des éléments de la matrice M de type MAT, nous
devons cumuler tous les éléments quelle contient.
Deux boucles complètes, une pour parcourir les lignes et l’autre pour parcourir les colonnes
de la matrice sont nécessaires.
Une initialisation à zéro de la variable Somme est obligatoire (traitement récurent d'ordre 1).
Pour ligne de 1 à N Faire
Pour colonne de 1 à N Faire
Somme Å Somme + M [ligne, colonne]

4INFINFRC0004  Page 1 
http://www.najah.com 

Fin Pour
Fin Pour
Fin Analyse

Algorithme de la fonction SOMME_MAT


0) Fonction Somme_Matrice (M : MAT ; N : Entier) : Entier
1) Somme Å 0
2) Pour ligne de 1 à N Faire
Pour colonne de 1 à N Faire
Somme Å S + M [ligne, colonne]
Fin Pour
Fin Pour
3) Somme_Matrice Å Somme
4) Fin Somme_Matrice

Tableau de codification des objets locaux :


Objets Type / Nature Rôle
Somme Entier Variable de cumul
ligne Entier Compteur des lignes de la matrice
colonne Entier Compteur des colonnes de la matrice

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;

III/ Algorithme récurrent sur les chaînes

Activité
Suite de Thue-Morse

4INFINFRC0004  Page 2 
http://www.najah.com 

Si on considère sur l’ensemble des chaînes constituées uniquement de "0" et de "1"(mots


binaires), la transformation qui consiste à remplacer toute occurrence du caractère "0" par la
chaîne "01" et toute occurrence du caractère "1" par la chaîne "10", on définit la suite de
Thue-Morse en partant de la chaîne "0" :

U0 Æ "0"
U1 Æ "01"
U2 Æ "0110"
U3 Æ "01101001"
U4 Æ "0110100110010110"
U5 Æ "0110 1001100101100110100110010110"
*-*-*-*-*-*-*-*-*-*-*

1/ Cette suite est-elle récurrente ?


Dans l’affirmative donnez son ordre.

2/ Ecrire un programme nommé Suite_Thue_Morse permettant de calculer et d'afficher les N


premiers termes de la suite de Thue-Morse à partir d’un caractère A ("0" ou "1") donnée.
-*-*-*-*-*-*-*-*-*-*-*-*-

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

Analyse du programme principal


Résultat : Ecrire ("La suite de Thue-morse à partir de ", A, " Est ", Fn Thue_Morse (N, A) )
Traitement : Thue_Morse est une fonction appelée au niveau du programme principal dans
un contexte d'affichage. Cette fonction génère la suite Thue_Morse à partir d'un caractère A
de départ qui est soit "0" sit "1".
Fin Saisie

Algorithme du programme principal


0) Début Suite_Thue_Morse
1) Saisie (N, A)
2) Ecrire ("La suite de Thue-morse à partir de ", A, " Est ", Fn Thue_Morse (N, A) )
3) Fin Suite_Thue_Morse

Tableau de codification des objets globaux :


Objets Type / Nature Rôle

4INFINFRC0004  Page 3 
http://www.najah.com 

N Entier Nombre d'éléments de la suite


A Caractère Caractère "0" ou "1"
Thue_Morse Fonction Fonction qui génère la suite Thue_Morse
Analyse de la fonction Thue_Morse
Résultat = Thue_Morse
Traitement :
- On initialise la chaîne de caractères Ch à la valeur de A
- On initialise un compteur j à la valeur 1. Ce compteur avance d'un pas de 2 car à chaque fois
on ajoute deux caractères "01 ou "10" à la chaîne Ch.
- On vérifie la valeur de CH[j], si elle vaut "0" alors on insère le caractère "1" dans la chaîne
Ch à la position J+1, sinon on insère le caractère "0" puis on incrémente de 2 le compteur j.
- On répète ce traitement N fois.
Fin Analyse

Algorithme de la fonction Thue_Morse


0) Fonction Thue_Morse (N : Entier ; A: Caractère) : Chaîne
1) CH Å A
2) Pour i de 1 à N Faire
jÅ1
Répéter
Si CH[j] = "0" Alors insère ("1", CH , j +1)
Sinon insère ("0", CH, j +1)
Fin Si
L Å Long (Ch)
jÅ j+2
Jusqu'à (j > L)
Fin Pour
3) Thue_Morse Å Ch
4) Fin Thue_Morse

Tableau de codification des objets locaux :


Objets Type / Nature Rôle
i Entier Compteur
j Entier Compteur
L Entier Longueur de la chaîne
Ch Chaîne Chaîne représentant la suite Thue_morse

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 ;

{========== Programme principal ===================}


BEGIN
Saisie (N, A) ;
WriteLn('La suite de Thue-morse à partir de ', A, ' Est ', Thue_Morse (N, A) ) ;
END .

IV/ Triangle de Pascal


Le triangle de Pascal est le tableau des coefficients qui sont utilisés pour le développement de
certaines expressions comme (a+b)² ou (a+b)n.
Cela s'appelle la "formule du binôme de Newton". Les coefficients s'appellent les
"coefficients binomiaux" ou "coefficients du binôme".

Ce triangle est le suivant :

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.

Pour n = 3, le Triangle de Pascal affiché est le suivant :

Ligne 1 1
Ligne 2 1 1
Ligne 3 1 2 1
Colonnes
1 2 3

MAT[3,2] = MAT[2,2] + MAT[2,1]

Pour n = 5, le Triangle de Pascal affiché est le suivant :

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

MAT[5,4] = MAT[4,4] + MAT[4,3]

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 

On se propose d’afficher les N premières lignes du Triangle de Pascal avec (3 ≤ N ≤ 100).

On rappelle que le principe de remplissage des n premières lignes de la matrice MAT


représentant le Triangle de Pascal est le suivant :

Pour une ligne donnée :


Le premier élément et le dernier élément sont égaux à 1,
Les autres éléments sont déterminés en appliquant la formule suivante :
MAT [ligne, colonne] = MAT [ligne-1, colonne] + MAT [ligne-1, colonne-1]

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

Analyse du programme principal


Résultat : Deux affichages d’une matrice contenant les différentes valeurs du Triangle de
Pascal, réalisé chaque fois par l'appel la procédure Afficher_Triangle
Traitement :
- Le premier affichage est celui de la matrice obtenue par le traitement itératif (Proc
Triangle_itératif).
- Le deuxième affichage est celui de la matrice obtenue par le traitement récursif (Proc
Triangle_récursif).
- L'entier N qui représente le nombre de lignes du Triangle, est lu par la procédure Saisie.
Fin analyse

Algorithme du programme principal


0) Début Triangle_Pascal
1) Proc Saisie (N)
2) Proc Triangle_itératif (N, MAT)
3) Proc Afficher_Triangle (N, MAT)
4) Proc Triangle_récursif (N, MAT)
5) Proc Afficher_Triangle (N, MAT)
6) Fin Triangle_Pascal

4INFINFRC0004  Page 7 
http://www.najah.com 

Tableau de codification des objets globaux :


Objets Type / Nature Rôle
N Entier Nombre de lignes du triangle de Pascal
MAT Matrice Représentant le Triangle de Pascal
Saisir Procédure Permet de saisir N le nombre de lignes du Triangle
Triangle_itératif Procédure Permet de remplir la matrice représentant le Triangle
de Pascal par un procédé itératif
Triangle_récursif Procédure Permet de remplir la matrice représentant le Triangle
de Pascal par un procédé récursif
Affiche_Triangle Procédure Permet d’afficher le Triangle de Pascal
Max_N Constante = 20 Nombre de lignes max du triangle

Tableau de codification des nouveaux types :


Type
Matrice = Tableau de 20 lignes et N colonnes d’entiers

Analyse de la procédure Triangle_iteratif


Résultat = Remplir la matrice MAT
Traitement : On constate que :
Ligne 1 Æ MAT [1,1] contient la valeur 1
Ligne 2 Æ MAT [2,1] et MAT [2,2] contiennent la valeur1
Ligne x Æ On utilise deux boucles : une pour les lignes et une autre pour les colonnes.
Pour ligne de 3 à N Faire
MAT [ligne, 1] Å 1 (première case de la ligne reçoit 1)
MAT [Ligne, Ligne] Å 1 (dernière case de la ligne reçoit 1)
Pour colonne de 2 à ligne -1 Faire
MAT [ligne, colonne] Å MAT [ligne - 1, colonne] + MAT [ligne -1, colonne -
1]
Fin Pour
Fin Pour

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 

Tableau de codification des objets locaux :


Objets Type / Nature Rôle
ligne Compteur Compteur des lignes de la matrice
colonne Compteur Compteur des colonnes de la matrice

Analyse de la procédure Triangle_récursif


Résultat : matrice remplie représentant le Triangle de Pascal
Traitement : Pour chacune des n lignes de la matrice, un parcourt des colonnes (de la
première à celle qui porte le numéro de la ligne), est nécessaire pour déterminer leurs valeurs
en faisant appel à la fonction récursive Val_Triangle.

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

Analyse de la fonction Val_Triangle


Résultat : Val_Triangle
Traitement : (déterminer une valeur du Triangle selon la ligne (x) et la colonne (y) données
comme paramètres).
Pour la première ligne, la valeur est égale à 1,
Si le numéro de ligne est égal au numéro de colonne, la valeur est aussi égale à 1,
sinon la valeur trouvée à l’intersection de la ligne x et de la colonne y est égale à (la valeur
trouvée à l’intersection de la ligne x et de la colonne y-1) + (la valeur trouvée à l’intersection
de la ligne x-1 et de la colonne y-1)
Fin Analyse

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

Analyse de la procédure Afficher_Triangle


Résultat = Afficher la matrice MAT

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

Algorithme de la procédure Afficher_Triangle


0) Procédure Afficher_Triangle (N : Entier ; MAT : Matrice)
1) Pour ligne de 1 à N Faire
Pour colonne de 1 à ligne Faire
Ecrire (Mat [ligne, colonne]," ") {Sans retour à la ligne}
FinPour
Ecrire ( ) {avec retour à la ligne}
FinPour
2) Fin Afficher_Triangle

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;

{=============== Programme principal ============== }


BEGIN

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 :

1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610............


Le nombre de couples de lapins Un à la saison n est égal au nombre de couples de lapins
adultes, c'est-à-dire le nombre total de lapins qu'il y avait à la saison précédente n-1, auquel on
ajoute le nombre de couples de jeunes lapins, qui est égal au nombre de couples de lapins
adultes à la saison précédente, donc au nombre total de couples à la saison n-2.

C'est pourquoi on a: Un = Un-1 + Un-2

Tout ceci est plus clair avec un tableau:

nombre de couples de nombre de couples de nombre total de couples de


saison n
lapins adultes ( = un-1) jeunes lapins (= un-2) lapins un (Fibo)
1 0 1 1
2 1 0 1
3 1 1 2
4 2 1 3
5 3 2 5
6 5 3 8
7 8 5 13
8 13 8 21
9 21 13 34

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

Donc c'est une suite récurrente d'ordre 2.

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.

*-*-*-*-*-*-*-*-*-*-*

Analyse du programme principal Suite_itérative_Fibonacci


Résultat : Ecrire ("Fibo de ", N, " = " , Valeur_Fibo)
Traitement :
- Une fonction itérative Fibo_Itérative retourne la valeur du Nième terme de la suite.
- Une procédure Saisie, assure la lecture et le test de l'entier N.
Fin Suite_itérative_Fibonacci

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

Tableau de codification des objets globaux :


Objets Type / Nature Rôle
N Entier Nombre de terme de la suite
Valeur_Fibo Entier Long Valeur de la suite

Analyse et algorithme de la procédure Saisie


- Voir les exemples précédents, car cette procédure à fait l'objet de plusieurs études.
Il est à noter qu'elle figure au niveau de la traduction en Pascal.

Analyse de la fonction Fibo_Itérative


Résultat = Fibo_Itérative
Traitement :

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

- Le résultat final est la dernière valeur obtenue


Fibo_Itérative Å Fibo
Fin Fibo_Itérative

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

Tableau de codification des objets locaux :


Objets Type / Nature Rôle
U1, U2 Entier Eléments de la suite
Fibo Entier Long Calcul de la suite
i Entier Compteur

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 

Analyse de la fonction Fibo_Tab


Résultat = Fibo_Tab
Traitement :
- On initialise les deux premières case du tableau T à 1.
T[1] Å 1
T(2] Å 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
Pour i de 3 à N Faire
T[i] Å T[i - 1] + T[i - 2]

- Le résultat final est la dernière valeur obtenue


Fibo_Itérative Å T[N]
Fin Fibo_Tab

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

Modification du tableau de codification des objets globaux :


Objets Type / Nature Rôle
N Entier Nombre de terme de la suite
Valeur_Fibo Entier Long Valeur de la suite
T Tab Tableau des termes de la suite
Nmax Constante = 50 Valeur maximal de N

Tableau de codification des nouveaux types


Types
Tab = Tableau de Nmax Entier Long

Tableau de codification des objets locaux :


Objets Type / Nature Rôle
Fibo Entier Long Calcul de la suite
i Entier Compteur

4INFINFRC0004  Page 16 
http://www.najah.com 

Traduction en Pascal de la fonction Fibo_Tab


FUNCTION Fibo_Tab (N : Integer ; T : Tab) : LongInt ;
VAR i : Integer ;
Fibo : LongInt ;
BEGIN
T[1] := 1 ;
T[2] := 1 ;
If (N < = 2) Then Fibo := 1
Else
For i := 3 To N Do
Begin
T[i] := T[i-1] + T[i-2] ;
End ;
Fibo := T[n] ;
Fibo_Tab := Fibo ;
END ;

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.

*-*-*-*-*-*-*-*-*-*-*

Analyse de la fonction Fibo_Récursive


Résultat = Fibo_Récursive
Traitement :
Le calcul de la fonction de Fibonacci fait référence aux deux éléments précédents.
Un = Un-1 + Un-2 Avec U1 = 1 et U2 = 1
PuisqueU3 fait référence à ces deux éléments précédents U1 et U2 qui sont connus, on peut
dire que U3 est aussi connu.
Pour un l'élément N on peut écrire :

Fibo_Récursive Å Fn Fibo_Récursive (N-1) + Fn Fibo_Récusive (N-2)

C'est un traitement récursif


Fin Analyse

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

Traduction en Pascal de la fonction Fibo_Récursif


FUNCTION Fibo_Recursif (N : Integer ) : LongInt ;
BEGIN
If (N < = 2) Then Fibo_Recursif := 1
Else
Fibo_Recursif := Fibo_Recursif (N-1) + Fibo_Recursif (N-2) ;
END ;

VI/ Le nombre d'or


Définition et valeur du nombre d'or
Le nombre d'or est la solution positive de l'équation : x2 -x -1 = 0

C'est-à dire le nombre (1 + 5 )/2

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:

Valeur exacte de Valeur approchée de


n Fib (n)
Fib (n+1) / Fib (n) Fib (n+1) / Fib (n)
1 1 1 1
2 1 2 2
3 2 3/2 1,5
4 3 5/3 1,666
5 5 8/5 1,6
6 8 13/8 1,625
7 13 21/13 1,615

4INFINFRC0004  Page 18 
http://www.najah.com 

Les 100 premières décimales du nombre d'or sont :


1,618 033 988 749 894 848 204 586 834 365 638 117 720 309 179 805 762 862 135 448 622
705 260 462 189 024 497 072 072 041

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:

1/0 = Ceci n'existe pas.


1/1 = 1
2/1 = 2
3/2 = 1.5 Fib (n + 1)
5/3 = 1.6666... = 1.6….
Fib (n)
8/5 = 1.6
13/8 = 1.625
21/13 = 1.61538...
34/21 = 1.61904...

Le nombre d'or, habituellement désigné par la lettre φ (phi) de l'alphabet grec.

Activité
Ecrire une fonction nommé Nombre_Or, qui retourne une approximation du nombre d'or avec
une précision de 10-6
*-*-*-*-*-*-*-*-*-*-*

Analyse de la fonction Nombre_Or


Résultat = Nombre_Or
Traitement :
On calcule en premier lieu la suite de Fibonacci dans un tableau.
U[i ] = U[i -1] + U[i - 2] avec U[1] = 1 et U[2] = 1
Fib (n + 1)
Puis on calcule La suite (Vn) définie sur N* par Vn = qui converge vers le
Fib (n)
nombre d'or.
V[i] = U[i] / U[i-1]

On répète ce calcul jusqu'à une précision donnée (par exemple de 10-6)


Fin Analyse
Algorithme
0) Fonction Nombre_Or (précision : Réel) : Réel ;
1) U[1]Å 1
U[2] Å 2
i Å 2;
2) Répéter
iÅ i+1
4INFINFRC0004  Page 19 
http://www.najah.com 

U[i] Å U[i-1] + U[i-2]


V[i] Å U[i] / U[i-1]
Jusqu'à ABS(V[i] - V[i-1]) < précision ;

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

II/ Exemples d'études arithmétiques :


II-1 - Calcul de PGCD (le Plus Grand Commun Diviseur)

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 

Sinon, a et b ont le même PGCD que b et le reste r de la division Euclidienne de a par


b
(r Å a MOD b).
Il s'agit d'un traitement répétitif qui s'arrête quand b sera égal à zéro.
Fin analyse

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

Tableau de déclaration des objets locaux


Objet Type / Nature Rôle
r Entier Reste de la division

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 

PGCD (22, 6) = PGCD (22-6, 6) = PGCD (16, 6) Car 22 > 6


= PGCD (16-6, 6) = PGCD (10,6) Car 16 > 6
= PGCD (10-6, 6) = PGCD (4, 6) Car 10 > 6
= PGCD (4, 6-4) = PGCD (4, 2) Car 4 < 6
= PGCD (4-2, 2) = PGCD (2,2) Car 4 > 2
=2

Analyse de la fonction PGCD


Résultat = PGCD

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

FUNCTION PGCD (a, b : Integer ) : Integer ;


BEGIN
IF a= b Then PGCD := a
Else If (a > b ) Then PGCD := PGCD (a-b, b)
Else PGCD := PGCD (a, b-a) ;
END;

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.

Le nombre d'arrangements de p éléments pris parmi n est :

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.

Analyse du programme Arrangement


Résultat = Ecrire ("A(n, p) = ", anp )
Traitement :
anp est calculé par la fonction Arrange (n, p)
n et sont saisie par la procédure Lecture (n, p)
Fin analyse

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

Tableau de déclaration des objets globaux


Objet Type / Nature Rôle
n Entier nombre d'éléments de l'ensemble
p Entier nombre d'éléments de l'arrangement
anp Entier Résultat de l'arrangement
Arrange Fonction Calcule l'arrangement
Saisie Procédure Saisie de p et n

Analyse de la procédure Saisie


Résultat = Saisie et test de n et p
Traitement
Répéter
n = Donnée
p = Donnée
4INFINFRC0005  Page 4 
http://www.najah.com 

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

Analyse de la fonction arrange


Résultat = arrange
Traitement :
Une itération complète permet le cumul de arrangement
Pour i de n à n-p+1 (pas -1 ) Faire
ar Å ar * i
Fin Pour
ar doit être initialiser à 1
ar Å 1
Fin Analyse

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

Tableau de déclaration des objets locaux


Objet Type / Nature Rôle
ra Entier Pour le calcul de l'arrangement

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.

On appelle permutation de n éléments tout arrangement de p éléments parmi n.

Le nombre de permutation d'un ensemble à n éléments est égal à n!.

4INFINFRC0005  Page 6 
http://www.najah.com 

Exemple : Nombre de permutations deux à deux de 3 lettres a, b et c donne


(a, b) ; (b, a) ; (a, c) ; (c, a) ; (b, c) ; (c, b)
On trouve six permutations (3! = 6)

Le nombre de combinaison des trois lettres a, b, c'est le nombre de permutations sans


tenir compte des ordres possibles ce qui donne :
(a, b) ; (a, c) ; (b, c);
On trouve 3 cas 3! / (2! * (3-2)!) = 6 / 2 * 1 = 3

C32 Qu'on notera C (3, 2) = 3

Le nombre de combinaisons de p éléments de l'ensemble E est représenté par la relation


suivante :

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.

Analyse du programme Combinaison


Résultat = Ecrire ("C(n, p) = ", cnp )
Traitement :
- Une procédure Saisie permet la saisie et le test de validité de p et n.
- Une fonction Combin renvoie C(n,p)
Fin analyse

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

Tableau de déclaration des objets globaux


Objet Type / Nature Rôle
n Entier nombre d'éléments de l'ensemble
p Entier nombre d'éléments de la combinaison
cnp Entier Résultat de la combinaison
Combin Fonction Calcule la combinaison
Saisie Procédure Saisie de n et p

Analyse de la procédure Saisie

4INFINFRC0005  Page 7 
http://www.najah.com 

Résultat = Saisie et test de n et p


Traitement
Répéter
n = Donnée
p = Donnée
Jusqu'à (0 ≤ p ≤ n)
Fin Saisie

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

Analyse de la fonction combin


Résultat = Combin
Traitement :
Une fonction factorielle sera appelée une première fois pour calculer n! et seconde fois pour
calculer p! et puis une troisième fois pour calculer (n-p)!
combin Å Fn Factorielle (n) / ( Fn Factorielle (p) * Fn Factoreille (n-p ) )
NB : Vous pouvez revoir l'étude de la fonction factorielle dans le chapitre la récursivité.
Fin Analyse

Algorithme
0) Fonction Combin (n, p : Entier) : Réel
1) combin Å Fn Factorielle (n) / ( Fn Factorielle (p) * Fn Factoreille (n-p ) )
2) Fin Combin

Algorithme de la fonction Factorielle


0) Fonction Factorielle (a : Entier) : Entier Long
1) F ← 1
2) Pour i de 2 à a Faire
F←F*i
Fin Pour
3) Factorielle ← F
4) Fin Factorielle

Tableau de déclaration des objets locaux


Objet Type / Nature Rôle
F Entier Long Pour le calcul de la factorielle

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 

II-4 - Conversion entre bases de numération

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.

1/ Analyse de la procédure Dec_Bin


Résultat = Afficher la conversion en binaire
Traitement :
- L'affichage du nombre binaire est l'affichage "inverse" du contenu d'un tableau T
- Le tableau T est remplit par les restes des divisions successives du nombre décimal (D) par
2, puisque le système binaire utilise la base 2 (B=2).
L'arrêt des divisions par 2 se fait lorsque D sera égal à 0.
Le nombre de division sera stocké dans la variable (compteur) C qui est initialisée à zéro.
Fin Analyse

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

2/ Analyse du programme conversions utilisant cette procédure.


Résultat = Conversion entre bases
Traitement :
La procédure nécessite la valeur du nombre décimal D, qui sera lu et tester par une procédure
nommée saisie.

Proc Saisie (D)


Proc DEc_Bin (D, Restes, C)
Fin Analyse

Algorithme
0) Début Conversions
1) Proc Saisie (D)
2) Proc Dec_Bin (D, Restes, C)
3) Fin Conversions

2/ Analyse de la procédure Saisie_Decimal


Résultat = Lecture et teste de l'entier positif D
Traitement :
Répéter
D = Donnée ("Entrer un entier positif ")
Jusqu'à (D > 0)
Fin Analyse

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

Tableau de déclaration des objets globaux


Objet Type / Nature Rôle
Restes TAB Tableau contenant la conversion en binaire
D Entier Le nombre décimal
C Entier Compteur
Saisie_Decimal Procédure Saisie du nombre décimal
Dec_Bin Procédure Conversion du décimal au binaire

Tableau de déclaration des nouveaux types


Types
TAB = Tableau de 100 chiffre
Chiffre = 0 .. 9

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]);

WriteLn (' en binaire') ;


END;

{ ============ P.P ==========================}


BEGIN
Saisie_Decimal (D) ;
Dec_Bin (D, Restes, C);
END.

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.

Analyse de la procédure Hex_Bin


Résultat = Afficher la conversion de l'hexadécimal en binaire
Traitement :
- Un chiffre hexadécimal correspond à 4 bits, il suffit de convertir en 4 bits chaque chiffre du
nombre hexadécimal et de les assembler dans le l'ordre.

Exemple : Conversion du nombre Hexadécimal 18BF en Binaire

1 8 B F
= = = =
0001 1000 1001 1111

Le nombre (18BF)16 vaut (0001100010011111)2


Les zéro en bleu ne servent à rien, on doit les supprimer, donc
Le nombre (18BF)16 vaut (1100010011111)2

- 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

Tableau de déclaration des objets globaux à ajouter au programme


Objet Type / Nature Rôle
Hex Chaîne Le nombre en hexadécimal
Ch_Binaire Chaîne Le nombre binaire
Car_Binaire Fonction Renvoie le binaire d'un chiffre Hexa

4INFINFRC0005  Page 14 
http://www.najah.com 

car Caractère Un caractère représentant un chiffre Hexa

Tableau de déclaration des objets locaux


Objet Type / Nature Rôle
i Entier Compteur

Analyse de la fonction Car_Binaire


Résultat = Car_Binaire
Traitement :
- Puisque chaque caractère représentant le chiffre hexadécimal va être convertit en 4 bits,
donc une variable Ch pour le cumul de la conversion peut être initialisée à "0000"
- Pour convertir le chiffre en binaire, on doit effectuer des divisions successives par 2 et les
restes seront placés directement dans la chaîne Ch à l'aide d'un compteur qui commence à
partir de la position 4 (le dernier digit des 4 bits). Bien sur ces restes seront convertit en
chaîne (ch_Reste) avant de les insérer.
- Le nombre hexadécimal comporte des caractères de "0" à "9" qu'on convertit directement
par la procédure prédéfinie Valeur (En Pascal Val) pour obtenir un entier N. Les caractères
"A" à "F" qu'on doivent être transformés en nombre (exemple "A" en 10), on utilise la
correspondance des codes ASCII pour obtenir l'entier N.
A = Ord("A") - 55 = 65 - 55 = 10
B = Ord ("B") -55 = 66 - 55 = 11 etc.

On arrête les divisions quand la valeur N correspondant au chiffre arrive à zéro.


iÅ4
Répéter
r Å N MOD 2
ConvCh (r, Ch_Reste)
Ch[i] Å Ch_Reste [1]
N Å N Div 2
i Å i - 1 { pointer le digit suivant des 4 bits}
Jusqu'à N = 0
Fin Analyse

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

Tableau de déclaration des objets locaux


Objet Type / Nature Rôle
N Entier Equivalent entier d'un caractère hexa
Ch Chaîne Pour le cumul du binaire d'un chiffre
r Entier Reste de la division par 2
Ch_Reste Chaîne [1] Equivalent de r en chaîne
Erreur Entier Numéro de l'erreur de la conversion
i Entier Compteur

2/ Analyse de la procédure Saisie_Hexa


Résultat = Lecture et teste de la chaîne Hex en Hexa
Traitement :
Répéter
Hex = Donnée ("Entrer un nombre hexadécimal ")
Jusqu'à (Long (hex ) > 0)
Fin Analyse

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

Ajout des procédures et des fonctions au programme Pascal


PROGRAM Conversions ;
USES Crt ;
TYPE
Chiffre = 0..9 ;
TAB = ARRAY [1.. 100 ] Of Chiffre ;
VAR
D, C : Integer ;
Restes : TAB ;

Hex, Ch_Binaire, Car_Binaire : String ;

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;

PROCEDURE Saisie_Hexa (VAR Hex : String ) ;


BEGIN
Repeat
Write ('Entrer un nombre hexadécimal : ') ;
ReadLn (Hex) ;
Until (Length (Hex) > 0) ;
END ;

FUNCTION Car_Binaire ( car : Char ) : String ;


VAR
N, r, erreur : Integer ;
Ch : String ;
Ch_Reste : String [1] ;
BEGIN
If Not (Car IN ['0' .. '9'])
Then N := Ord (Car) - 55
Else Val (Car, N, Erreur);

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 ;

PROCEDURE Hex_Bin (Hex : String ; VAR Ch_Binaire : String ) ;


BEGIN
Ch_Binaire := '' ;
FOR i := 1 To Length (Hex) Do
Ch_Binaire := Ch_Binaire + Car_Binaire ( Hex[i] ) ;
WriteLn (hex, ' En hexadécimal, vaut ', Ch_Binaire, ' en binaire') ;
END ;

{ ============ P.P ==========================}


BEGIN
Saisie_Decimal (D) ;
Dec_Bin (D, Restes, C);

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.

Analyse de la procédure Bin_Oct


Résultat = Afficher la conversion du binaire en octal
Traitement :
- Le plus grand chiffre octal est 7, qui convertit en binaire, donne 111
Donc un chiffre de l'octal correspond à 3 bits, il suffit de grouper par 3 les chiffres du nombre
binaire puis de convertir chaque groupe on utilisant le système de pondération. L'assemblage
dans l'ordre des chiffres trouvés donne le nombre octal correspondant.

Exemple : Conversion du nombre binaire 1001100101 en Octal

4INFINFRC0005  Page 18 
http://www.najah.com 

1 001 100 101


= = = =
1*20 0*22 + 0*21+ 1*20 1*22 + 0*21+ 0*20 1*22 + 0*21+ 1*20
= = = =
1 1 4 5

Le nombre (1001100101)2 = (1145)8

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

ConvCh (Oct_tmp, Ch_oct_tmp)


Oct Å Ch_oct_tmp + Oct
LÅL-3
Fin Pour
Bin_Oct Å Oct ;
4) Fin Bin_Oct

Tableau de déclaration des objets locaux


Objet Type / Nature Rôle
Ch_binaire Chaine Le nombre binaire
N Entier Nombre de tranches de 3 de Ch_Binaire
Oct Chaîne Le nombre en octal
Ch_oct_tmp Chaîne Une partie du nombre octal
L Entier Longueur du nombre binaire
i Entier Compteur
Ch_tmp Chaîne Contient l'extraction de 3 caractères
Oct_tmp Entier Un chiffre du nombre octal
j Entier Compteur
a Entier Contient la conversion de ch_tmp en nombre
Fn Fonction calcul 2 3-j
Puissance_2 Entier test pour la fonction valeur
erreur

Analyse de la fonction Puissance_2


Résultat = Puissance_2
Traitement :
Calculer 2 x
vÅ1
Pour i de 1 à x Faire
vÅ v*2
Fin Pour
Puissance_2 Å v
Fin

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

Tableau de déclaration des objets locaux


Objet Type / Nature Rôle
v Entier Variable temporaire pour le calcul du produit
i Entier Compteur

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;

STR (Oct_tmp, Ch_oct_tmp) ;


Oct := Ch_oct_tmp + oct;
L := L - 3 ;
End ;
Bin_Oct := Oct ;
END ;

{ ========= P P ============== }
BEGIN

{ Saisie du nombre binaire et test de ses chiffres 0 ou 1 }


Repeat
Write('Donner un nombre binaire : ');
ReadLn (ch_binaire);
test := false;
For i:= 1 to Length (ch_binaire) Do
If (ch_binaire [i] <> '1') AND (ch_binaire [i] <> '0')
Then Test := True ;
Until Test = False ;
{ Fin saisie et test }

WriteLn ( Bin_Oct (Ch_binaire) );


END.

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 

Analyse du programme principal B1_B2


Résultat = Ecrire (NB1, " écrit dans la base ", B1, " vaut : ", NB2, " Dans la base ", B2)
Traitement :
-NB2, le résultat est donné par la fonction Convert, qui convertit le NB1 de la base B1 dans la
base B2.
- NB1 est une chaîne de caractère car Nb1 représente le nombre dans la base B1 qui peut être
une base supérieure à la base 10.
- Une procédure Saisie_NB1, permet la saisie et le test de ce nombre qui doit être composé
que des chiffres de la base B1.
- Une procédure Lecture permet la saisie et le test des deux valeurs des deux bases B1 et B2.
Fin Analyse

Algorithme du programme principal


0) Début B1_B2
1) Proc Lecture (B1, B2)
2) Proc Saisie_NB1 (B1, NB1)
3) NB2 Å Fn Convert (NB1, B1, B2)
4) Ecrire (NB1, " écrit dans la base ", B1, " vaut : ", NB2, " Dans la base ", B2)
5) Fin B1_B2

Tableau de déclaration des objets locaux


Objet Type / Nature Rôle
B1 Entier La première base
B2 Entier La deuxième Base
NB1 Chaîne Le nombre de B1
NB2 Chaîne Le nombre en B2
Convert Fonction Convertit NB1 dans B2

Analyse de la fonction Convert


Résultat = Convert
Traitement :
- La conversion se fera :
- En premier lieu de la base B1 vers la base 10, on obtient le nombre NB10 renvoyé
par la fonction Convert_B10
- En second lieu de la base 10 vers la base B2, à l'aide de la fonction Convert_B2.

Fin Analyse

Algorithme de la fonction Convert


0) Fonction Convert (NB1 : Chaîne; B1, B2 : Entier ) : Chaîne
1) NB10 Å Fn Convert_B10 (NB1, B1)
2) Ch_B2 Å Fn Convert_B2 (NB10, B2)
3) Convert Å Ch_B2
4) Fin Convert

Tableau de déclaration des objets locaux

4INFINFRC0005  Page 23 
http://www.najah.com 

Objet Type / Nature Rôle


NB10 Entier Long le nombre en base 10
Ch_B2 Chaîne Le nombre dans la base B2
Fn Convret_B10 Fonction Convertit d'une base B vers le décimal
Fn Convert_B2 Fonction Convertit du décimal vers B2

Analyse de la fonction Convert_B10


Résultat = Convert_B10
Traitement :
- Chaque chiffre de NB1 sera convertit en valeur numérique puis il sera multiplié par la valeur
de la base élevée à la puissance relative à son Rang.
Cette tâche sera réalisée par une fonction nommée puissance_B1.
Le nombre trouvé sera ajouté au nombre dans la base décimale (D10).

Exemple : NB1 = "1A2" dans la base 16


D10 = 1 *162 + 10*161 + 2*160
Pour obtenir la valeur des caractères "A" .. "F" de la base 16, on applique la relation suivante
sur les codes ASCII.
N Å Ord ( NB1[i]) - 55
Sinon on convertit en valeur les autres caractères.
Une itération complète permet de parcourir toute la chaîne NB1
D10 Å 0
L Å Long (NB1)
Pour i de L à 1 (pas -1) Faire
Si (NB1[i] ) Dans ["A" .. "F"]
Alors N Å Ord (NB1[i]) - 55
Sinon Valeur (NB1[i], N, erreur)
Fin Si

D10 Å D10 + N * Fn Puissance_B1 (L -i, B1)


Fin Pour
Convert_B10 Å D10
Fin Analyse

Algorithme de la fonction Convert_B10


0) Fonction Convert_B10 (NB1 : Chaîne; B1 : Entier) : Entier Long
1) D10 Å 0
2) L Å Long (NB1)
3) Pour i de L à 1 (pas -1) Faire
Si (NB1[i] ) Dans ["A" .. "F"]
Alors N Å Ord (NB1[i]) - 55
Sinon Valeur (NB1[i], N, erreur)
Fin Si

D10 Å D10 + N * Fn Puissance_B1 (L -i, B1)


Fin Pour

4INFINFRC0005  Page 24 
http://www.najah.com 

4) Convert_B10 Å D10
5) Fin Convert_10

Tableau de déclaration des objets locaux


Objet Type / Nature Rôle
D10 Entier Long Le nombre en base 10
L Entier Longueur de la chaîne NB1
i Entier Compteur
N Entier Conversion des caractères Hex en nombre
erreur Entier test pour la fonction valeur
Puissance_B1 Fonction Calcule B1x

Analyse de la fonction Puissance_B1


Résultat = Puissance_B1
Traitement :
Calculer B1 x
vÅ1
Pour i de 1 à x Faire
v Å v * B1
Fin Pour
Puissance_B1 Å v
Fin

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

Tableau de déclaration des objets locaux


Objet Type / Nature Rôle
v Entier Variable temporaire pour le calcul du produit
i Entier Compteur

Analyse de la fonction Convert_B2


Résultat = Convert_B2
Traitement :
- Concaténer les restes des divisions successives du nombre décimal NB10 par B2. La
répétions de ces divisions s'arrête quand le quotient devient nul.
- La concaténation des restes se fait dans une variable de type chaîne de caractères qui doit
être initialisée à vide (Ch Å "").

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

Tableau de déclaration des objets locaux


Objet Type / Nature Rôle
Reste Entier Variable temporaire pour le calcul du reste
Ch_Reste Chaîne L'équivalent de reste en chaîne
Ch Chaîne Cumul du nombre en B2

Analyse de la procédure Lecture


Résultat = Saisie et test des valeurs des deux bases B1 et B2
Traitement :
Lecture de B1 tel que 2 ≤ B1 ≤ 16
Lecture de B2 tel que (2 ≤ B2 ≤ 16) et (B2 ≠ B1)
Fin Analyse

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

Analyse de la procédure Saisie


Résultat = Saisie et test du nombre NB1 de la base B1
Traitement :
- Le nombre NB1 est saisit sous forme d'une chaîne de caractère car B1 peut être supérieure à
10.
- NB1 doit contenir seulement les chiffres de la base B1, on teste tous les caractères de ce
nombre par rapport à l'ensemble des chiffres de la base B1.
- Pour faciliter les tests, les caractères de NB1 sont convertit en majuscule.

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

Tableau de déclaration des objets locaux


Objet Type / Nature Rôle
Test Booléen Drapeau de test
Ch Chaîne Sous chaîne construite
i Entier Compteur
NBX Constante =
"0123456789ABCDEF" Tous les caractères des bases ( B1 à B16)

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);

ch := Copy (NBX, 1 , B1);

For i:= 1 To Length(NB1) Do


begin
NB1[i] := UpCase (NB1[i]);
IF pos(NB1[i], ch) = 0 Then test := true ;
end;

Until test = False ;


END ;

{------------------------------------------------------------}
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 

Else Val(NB1[i], N, erreur) ;

D10 := D10 + N * Puissance_B1 (L - i, B1) ;


End ;
Convert_B10 := D10 ;
END ;

{------------------------------------------------------------}
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 

II-5 - Quelques règles de divisibilité

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.

Exemple 2 : Soit le nombre : 30086.


3008 - 2*6 = 2996
299 -2*6 =287
28 -2*7=14
14 étant divisible par 7 Î 30086 l'est aussi !

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

Les algorithmes d'approximation


I/ Introduction :
Ce chapitre traite des problèmes un peu plus complexes que les problèmes classiques déjà vus
comme de nouvelles méthodes de recherche, de tri, d'approximation ou d'optimisation.

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é.

Des questions se posent :


Un algorithme peut-il donner une solution exacte en un temps raisonnable ?
Peut-on trouver une solution approchée c'est-à-dire des approximations quand les algorithmes
exacts sont irréalisables?

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)

3.141592653359120552148830583971227448751686687114821 Log (28102/1277)**125/123

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 + ….

Ecrire unn programmee nommé PI_


_Euler, qui permet
p de tesster cette forrmule.

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)

Epsilon peur être une donnée ou une constante fixée à l'avance.


Fin Analyse

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

Tableau de codification des objets globaux


Objets Type/Nature Rôle
i Entier long Compteur
S1 Réel Somme 1
S2 Réel Somme2
Epsilon Réel Précision pour l'approximation

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 ;

Valeur := SqrrT (6 * S2) ;


V
W
WriteLn ('Valleur approchhée de PI est ', Valeur ) ;
END.

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

On arrêteera les calculls lorsque

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.

Analysee du progrramme prrincipal


Résultat = Ecrire (" X = ", x , ' S = ",s , " avvec ", n, " itérrations avec une précisioon ", EPS)
Traitemeent :
- Une proocédure CA ALCUL, calcculera la valeeur approchéée de la sériee ainsi que lee nombre
d'itérationns effectuéess.

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

Tableau de codification des objets globaux


Objet Type / Nature Rôle
x Réel Valeur de x
s Réel Calcul de la somme
n Entier nombre d'itération
EPS Constante = 10-6 précision de calcul

Analyse de la procédure ENTREE


Résultat = Lecture et test de x
Traitement :
Répéter
x = Donnée ("Entrer la valeur de x entre -50 et 50 ")
Jusqu'à (x ≥ -50) ET (x ≤ 50)
Fin analyse

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

Analyse de la procédure CALCUL


Résultat = calculer s
Traitement :
Une itération à condition d'arrêt Répéter .. jusqu'à la précision EPS permet de calculer la
valeur de s ainsi que le nombre d'itérations n.
- Initialiser n à 0
- Initialise une variable U à 1 (car U0 = 1 )
- Initialiser s à zéro
- Incrémenter n de 1 n Å n + 1
- Calculer U Å U * x/n

4INFINFRC0006  Page 5 
http://w
www.najaah.com 

- Cumuleer la valeur de
d s sÅ s+U

- La conddition d'arrêtt est

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

Tableau de codificattion des objjets locaux


Objeet Type
T / Natu
ure Rôlle
U Réeel Elém
ment de la suuite

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

Les algorithmes avancés


I/ Introduction :
Ce chapitre traite des problèmes un peu plus complexes que les problèmes classiques déjà vus
comme de nouvelles méthodes de recherche, de tri, d'approximation ou d'optimisation.
La résolution de ces problèmes demande, en grande partie, une recherche et un
développement par l'élève pour écrire des algorithmes corrects et efficaces.
Les algorithmes avancés utilisent le principe "diviser pour régner (divide to conquer) ", ce
principe consiste à résoudre un problème en résolvant deux ou plusieurs problèmes du même
type (similaires), en simplifiant le premier problème par des sous -problèmes simplifiés.

Attention, ce n’est pas la même chose que la programmation structurée où le


programmeur divise le problème en modules pour simplifier sa résolution. Ici c'est le
programme qui divise le problème et non le programmeur.

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.

Comment choisir le pivot ?


Nous pouvons choisir comme pivot l’élément situé au milieu de la partie à trier. Comme on
peut choisir le premier élément.

4INFINFRC0007  Page 1 
http://www.najah.com 

Comment réaliser une partition ?


¾ On considère que le pivot est le premier élément du tableau que l’on cherche à le
mettre à sa bonne place définitivement.
1 I=2 3 4 5 6 7 8 9 J=10

T 10 6 8 13 19 2 1 31 3 11
Pivot

¾ On fait un balayage par la gauche à partir du deuxième élément (I=2), on ne touche


pas à un élément si sa valeur est inférieure au pivot. On arrête ce balayage dès que
l’on trouve un élément dont la valeur est plus grande que celle du pivot que l’on
appelle G.
¾ On passe à un balayage par la droite en partant du dernier élément du tableau
(J=10). On ne touche pas à un élément si sa valeur est supérieure au pivot. On arrête
ce balayage dès que l’on trouve un élément dont la valeur est plus petite que celle du
pivot que l’on appelle P.
¾ On procède à l’échange des deux éléments G et P mal placés dans chacun des sous
listes.
1 2 3 I=4 5 6 7 8 J=9 10

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 

On permute le pivot avec l’élément ayant cet indice.


1 2 3 4 I=5 I=J=6 J=7 8 9 10

Pivot
T
10 6 8 3 1 2 19 31 13 11
Permuer

4INFINFRC0007  Page 3 
http://www.najah.com 

1 2 3 4 I=5 I=J=6 J=7 8 9 10

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

III/ Lees tours de


d Hanoï
Présenttation :

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

b- le nombre de déplacement de disques nécessaire pour arriver à l'état final est 7.

Tableau des résultats pour un nombre de disques allant de 1 à 10.


Nombre
1 2 3 4 5 6 7 8 9 10
de disques
Nombre
1= 3= 7= 15 = 31 = 63 = 127 = 255 = 511 = 1023=
de
2 - 1 2 - 1 2 - 1 24 - 1 25 - 1 26 - 1 27 - 1 28 - 1 29 - 1
1 2 3
210 - 1
déplacements

De façon générale, le nombre de déplacements pour n disques est 2n - 1.

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 déplace le disque "N" du taquet initial vers le taquet final Æ milieu


- on déplace les "N-1" disques du taquet intermédiaire vers le taquet final.

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.

Il existe une solution récursive très classique pour résoudre ce problème :


Supposons qu'on sache déplacer N-1 disques. Pour en déplacer N, il suffit de déplacer (N-1)
disques du piquet A (départ) au piquet C (intermédiaire),

S'il y a au moins un disque sur le piquet A, on appelle la procédure Hanoi, en précisant le


nombre de disques N, le piquet de départ, celui d'intermédiaire.
Si (N >0) Alors Proc Hanoï (N-1 , départ, intermédiaire, cible)
Affichage de l'état des disques sur les piquets.
Ecrire ("Disque du taquet ", départ, " vers le taquet ", intermédiaire)
Puis de déplacer le grand disque du piquet 1 au piquet 2,
On termine en déplaçant les (N-1) autres disques du piquet 3 vers le piquet 2.
Proc Hanoï (N-1, cible, départ, intermédiaire)
Fin Si
Voilà donc le problème résolu pour N disques, en partant du principe que vous savez le
résoudre pour N-1 disques.
Mais nous savons aussi résoudre le problème pour 0 disques : il n'y a rien à faire (aucun
déplacement). Nous savons donc résoudre le problème des tours de Hanoï pour tout n.

Tableau de codification des objets globaux


Objets Type/Nature Rôle
N Entier Nombre de disques
départ Caractère piquet 1
cible Caractère piquet 2
intermédiaire Caractère piquet 3

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ï

Programme complet en Pascal


Program Tours_Hanoi;
Uses Crt ;
Var n : Integer ;

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 ;

{ ========= Programme Principal ======= }


BEGIN
Repeat
WriteLn ('Combien de disques ?' ); ReadLn (n) ;
Until n IN [1 .. 64] ;
Hanoi (n, 1, 3, 2);
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).

Même si la légende est vraie, il nous reste beaucoup à vivre.

4INFINFRC0007  Page 9 
http://www.najah.com 

IV/ Le problème du voyageur de commerce (PVC)


Présentation :
Un voyageur de commerce doit visiter n villes données en passant par chaque ville une et une
seule fois. Il commence par une ville quelconque et termine en retournant à cette ville de
départ. Les distances entre les villes sont en général différentes mais elles sont connues.
Quel chemin faut-il choisir afin de faire le parcourt le plus court ?

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.

Le nombre de possibilités (nombre de trajets possibles) est de (n-1)! / 2.


Le tableau suivant montre le nombre de trajets possibles, et le temps de calcul estimé pour
évaluer tous ces trajets (On considère que l'on évalue un trajet en 1 microseconde - ce qui est
déjà très rapide) :
Nb de villes Nb de possibilités Temps de calcul
5 12 12 microsecondes
10 181 440 0,18 seconde
15 43 milliards 12 heures
20 60 E+15 1928 ans
25 310 E+21 9,8 milliards d'années (!)

C'est ce qu'on appelle l'explosion combinatoire.


C'est le nombre de trajets de peu d'intérêt que l'on teste qui limite cet algorithme : Quand on
teste toutes les possibilités, on teste même les plus absurdes.

Il faut donc trouver un autre algorithme pour résoudre le problème, qui trouverait dans un
temps raisonnable une solution approchée.

Les méthodes de résolution peuvent être classées en deux catégories :

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 :

Méthodes exactes "Branch and bound"


[Record 13509 villes], approximations garanties.

Méthodes approchées Algorithme gloutons, Méthodes de descente, Recuit simulé,


Algorithme tabou, Algorithmes génétique, Algorithme de Lin et Kerningham, Colonies de
fourmis, Etc.
NB : L'étude de ces méthodes ne fait pas partie du programme officiel

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

Résultat : Afficher les chemins et les distances des villes à visiter


Traitement : Affichage de liste et des distances des n villes à visiter. Ce traitement est réalisé
par la procédure Affichage_liste.

- 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.

Structure de données adéquates :


- On fixe tout d'abord le nombre maximum des villes à visiter, par exemple 20.
- Pour une ville, il nous faut son nom (une chaîne de caractères) et ses coordonnées (deux
réels). Une structure enregistrement "ville" est nécessaire.
- Pour stocker la liste des N villes, un tableau "T" d'enregistrements (ville) est indispensable.
- Une variable "v_départ" de type (ville) nous permet de saisir la ville de départ.
- deux autres variables "dist" pour calculer la distance entre deux villes et "disttot" pour
calculer la distance totale parcourue par le voyageur.

4INFINFRC0007  Page 11 
http://www.najah.com 

- Le nombre de ville "N"


- Une variable booléenne "existe" pour le test de l'existence ou non de la ville de départ.
Fin Analyse

Algorithme du programme principal


0) Début voyageur
1) disttot Å 0 {initialisation à zéro de la distance totale parcourue}
2) existe Å Faux {initialisation à Faux de la variable de test pour la saisie de la ville de
départ}
3) Proc Saisie_liste (N, T)
4) Proc Saisie_ville_départ (v_départ)
5) Proc Trajet (v_départ, dist, disttot)
6) Fin voyageur

Tableau de codification des nouveaux types


Type
Ville : Enregistrement
nom : Chaîne [16];
x, y : Réel ;
Fin Ville

Town = Tableau de nbmaxville Ville ;

Tableau de codification des objets globaux


Objet Type / Nature Rôle
nbmaxville Constante = 20 Nombre maximum de villes à visiter
N Entier Le nombre de villes à visiter
T Town Tableau des villes (tableau d'enregistrements)
dist Réel Distance entre deux villes
disttot Réel Distance totale parcourue
v_départ Ville nom et coordonnées de la ville de départ
Saisie_liste Procédure Saisie de la liste des villes
Saisie_ville_départ Procédure Saisie le nom et les coordonnées de la ville de départ
Trajet Procédure Détermine le trajet et calcule les distances

Analyse de la procédure saisie_liste


Résultat : Saisie du nombre de ville N et de la liste des noms et des coordonnées de ces N
villes.
Traitement :
Saisir le nombre N de villes
Répéter

4INFINFRC0007  Page 12 
http://www.najah.com 

Ecrire (" Combien de ville voulez vous visiter ? ")


Lire (N)
Jusqu'à (N > 0) ET (N < nbmaxville)

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

Tableau de codification des objets locaux


Objet Type / Nature Rôle
i Entier compteur
j Entier compteur
cestbon Booléen variable de test
city ville
Saisie_ville Procédure Saisie du nom et des coordonnées d'une ville

Algorithme la procédure saisie_liste


0) PROCEDURE saisie_liste (VAR n : Entier ; VAR T : town )

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

Analyse de la procédure saisie_ville


Résultat : saisie du nom et des coordonnées d'une ville
Traitement : Saisir le nom, l'abscisse x et l'ordonnée y d'une ville
Ecrire ("Entrer le nom de la ville : ") ; Lire (city.nom)
Ecrire ("Entrer l'abscisse de la ville : ") ; Lire (city.x)
Ecrire ("Entrer l'ordonnée de la ville: ") ; Lire (city.y)
Fin Saisie_ville

Algorithme la procédure saisie_ville


0) PROCEDURE saisie_ville (VAR city : ville)
1) Ecrire ("Entrer le nom de la ville : ") ; Lire (city.nom)
2) Ecrire ("Entrer l'abscisse de la ville : ") ; Lire (city.x)
3) Ecrire ("Entrer l'ordonnée de la ville: ") ; Lire (city.y)
4) Fin saisie_ville

Analyse de la procédure saisie_ville_départ


Résultat : saisie et valide la ville de départ
Traitement : Saisir le nom et les coordonnées de la ville de départ, puis parcourir la liste des
villes (le tableau T) pour confirmer que le nom et les coordonnées y figurent.
Sauvegarder son emplacement pour démarrer la recherche du chemin le plus court.
Une variable Booléenne "existe" est utilisée pour le test.
Répéter
Ecrire ("Veuillez saisir le nom de la ville de départ ? ")

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

Algorithme de la procédure saisie_ville_départ


0) PROCEDURE Saisie_ville_depart (VAR v_depart : ville ; VAR placeville : Entier)
1) Répéter
Ecrire ("Veuillez saisir le nom de la ville de départ ? ")
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)
2) Fin saisie_ville_départ

Tableau de codification des objets locaux


Objets Type/Nature Rôle
i Entier compteur
existe booléen variable de test

Analyse de la procédure trajet


Résultat : chercher le trajet le plus court en fonction des distances
Traitement : Nous connaissons l'emplacement de la ville de départ et son emplacement
(procédure saisie_ville_départ).
- On permute dans le tableau T l'emplacement de la ville de départ avec la nième ville.

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

Proc ville_plus_proche (T, placeville, dist)


disttot Å disttot + dist
Proc supprime_ville (T, v_depart)
v_depart Å T[placeville]

Ecrire ("ville suivante : ", v_depart.nom)


Ecrire ("Distance entre les deux dernière ville : ", dist)
Fin tant que
Ecrire ("Distance totale : ", disttot) ;
Fin trajet

Algorithme de la procédure trajet


0) PROCEDURE Trajet (v_depart : ville ; dist, disttot : Réel; Placeville : Entier)
1) Ecrire ("Premiere ville : ", v_depart.nom)
2) Tant Que ( n >1) Faire
T[placeville] Å T[n]
T[n] Å v_depart
Proc ville_plus_proche (T, placeville, dist)
disttot Å disttot + dist
Proc supprime_ville (T, v_depart)
v_depart Å T[placeville]
Ecrire ("ville suivante : ", v_depart.nom)
Ecrire ("Distance entre les deux dernière ville : ", dist)
Fin Tant Que
3) Ecrire ("Distance totale : ", disttot)
4) Fin trajet

Analyse de la procédure ville_plus_proche


Résultat : chercher le ville la plus proche de "la ville de départ"
Traitement : une fonction distance sera appelée pour calculer la distance entre deux villes.
distance ( T[i], T[j]);
- On calcule la distance entre la première ville de T et la dernière.
Pproche Å 1

4INFINFRC0007  Page 16 
http://www.najah.com 

dist Å distance (T[1], T[n])


- On parcourt le tableau de 2 à N-1 pour calculer et chercher la distance la plus petite ainsi que
l'emplacement (l'indice de la ville correspondante).
Pour i de 2 To N -1 Faire
Si (distance (T[i], T[n]) < dist) Alors
dist Å distance (T[i], T[n])
pproche Å i
Fin Si
Fin Pour
Fin ville_plus_proche

Tableau de codification des objets locaux


Objets Type/Nature Rôle
i Entier compteur

Algorithme de la procédure ville_plus_proche


0) PROCEDURE ville_plus_proche ( T : town; VAR pproche : Entier; VAR dist : Réel)
1) Pproche Å 1
2) dist Å distance (T[1], T[n])
3) Pour i de 2 à n-1 Faire
Si (distance (T[i], T[n] ) < dist) Alors
dist Å distance (T[i], T[n])
pproche Å i
Fin Si
Fin Pour
4) Fin ville_plus_proche

Analyse de la fonction distance


Résultat : distance
Traitement : la distance entre deux points A de coordonnées (x1, y1) et B de coordonnées
(x2, y2) est donnée par la formule
AB = ( x 2 − x1)² + ( y 2 − y1)²

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

Tableau de codification des objets locaux


Objets Type/Nature Rôle
xx Réel pour la ville 1
yy Réel pour la ville 2
d Réel pour la distance

4INFINFRC0007  Page 17 
http://www.najah.com 

Algorithme de la fonction distance


0) FONCTION distance (v1, v2 : ville) : Réel
1) xx Å v1.x - v2.x
2) yy Å v1.y - v2.y
3) d Å racine carrée (Carré (xx) + Carré (yy))
4) distance Å d
5) Fin distance

Analyse de la procédure supprime_ville


Résultat : Supprimer une ville de la liste
Traitement :
Parcourir le tableau à la recherche d'une ville donnée
Pour i de 1 To N Faire
Si (T[i].nom = city.nom) Alors

Cette ville va être supprimé, donc le nombre de villes diminue de 1.


NÅN-1

Supprimer la ville du tableau T par décalage des autres enregistrements.


Pour j de i à N Faire
T[j] Å T [j +1]
Fin Pour
Fin supprime_ville

Tableau de codification des objets locaux


Objets Type/Nature Rôle
i,j Entiers compteurs

Algorithme de la fonction distance


0) PROCEDURE supprime_ville (VAR T : town ; city : ville)
1) Pour i de 1 à N Faire
Si (T[i].nom = city.nom) Alors
NÅN-1
Pour j de i à n Faire
T[j] Å T [j + 1]
Fin Pour
Fin Si
Fin Pour
2) Fin supprime_ville

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 

trajet (v_depart, dist, disttot, Placeville);


END.

V/ Le problème des huit dames


Présentation :
Le problème des huit dames, consiste à trouver comment placer huit dames d'un jeu d'échecs
sur un échiquier de 8×8 cases sans que les dames ne puissent se menacer mutuellement
(qu'aucune ne puisse prendre les autres), conformément aux règles du jeu d'échecs. Par
conséquent, deux dames ne devraient jamais partager la même rangée, colonne, ou diagonale.

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.

Les illustrations sont du site http://fr.wikipedia.org/wiki/Problème_des_huit_dames

4INFINFRC0007  Page 22 
http://www.najah.com 

Pour N dames nous avons les solutions suivantes :

N Solutions N Solutions N Solutions

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

b) Algorithme du programme principal


0) Début Huit Dames
1) solution Å 0 { initialisation du nombre de solutions possibles }
2) Proc init (T, nbd)
3) Proc place_dame (T, 1)
4) Ecrire ("Nombre de solutions = ", solution)
5) Fin Huit Dames

Tableau de codification des objets globaux


Objets Type/Nature Rôle
nbd constante = 8 Nombre maximal de dames
nDames Entier Nombre de dames placées
T Tab tableau des positions des dames
solution Entier nombre de solutions trouvées
init Procédure Initialise à zéro le tableau
affiche Procédure Affiche la position des dames
place_dame Procédure Position des dames dans l'échiquier
Tableau de codification des nouveaux types
Type
Tab : tableau de nbd entiers

c) Analyse de la procédure init


Résultat :
Initialiser à zéro tous les éléments du tableau
Traitement :
Pour i de 1 à nbd Faire
T[i] Å 0
Fin Pour
Fin Analyse

Tableau de codification des objets locaux


Objets Type/Nature Rôle
i Entier compteur

d) Algorithme de la procédure init


0) Procédure init (VAR T : Tab ; nbd : Entier)
4INFINFRC0007  Page 25 
http://www.najah.com 

1) Pour i de 1 à nbd Faire


T[i] Å 0
Fin Pour
2) Fin init

e) Analyse de la procédure affiche


Résultat :
Afficher les positions des dames sur l'échiquier
Traitement :
On parcourt le tableau T contenant les positions de l'emplacement des différentes
dames. Si la dame existe, on affiche "1" sinon on affiche "0"
Pour i de 1 à nbd Faire
Pour j de 1 à nbd Faire
Si (j =T[i]) Alors Ecrire ("1") Sinon Ecrire ("0")
Fin Si
Fin Pour
Fin Pour
Fin Analyse

Tableau de codification des objets locaux


Objets Type/Nature Rôle
i,j Entier compteurs

f) Algorithme de la procédure affiche


0) Procédure affiche (T : Tab ; nbd : Entier)
1) Pour i de 1 à nbd Faire
Pour j de 1 à nbd Faire
Si (j =T[i]) Alors Ecrire ("1") Sinon Ecrire ("0")
Fin Si
Fin Pour
Fin Pour
2) Fin affiche

g) Analyse de la procédure place_dame


Résultat :
Remplir le tableau T par les positions des dames pour une solution
Traitement :
La procédure place_dame place 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.
Dans le tableau T l'indice i, indique la ligne de l'échiquier et le contenu de la case numéro i
(T[i]) indique la colonne de l'échiquier.
Le test suivant évite de mettre une dame sur la même ligne et 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)))

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

Tableau de codification des objets locaux


Objets Type/Nature Rôle
suivant label (étiquette) nom de l'étiquette
i, j Entiers Compteurs
affiche affiche Procédure qui affiche les 8 dames sur un échiquier

h) Algorithme de la procédure place_dame


0) Procédure place_dame (T : Tab ; nDames : Entier)
1) Si (nDames = nbd +1) Alors
Proc Affiche (T, nbd)
solution Å solution + 1
Fin Si
2) Pour i de 1 à nbd Faire
Pour j de 1 à ndames Faire
Si ((T[j] = i) OU (Abs (T[j] - i) = Abs (j - nDames))) Alors
Aller à Suivant
Fin Si
Fin Pour
T[nDames] Å i
Proc place_dame (T, ndames +1) {appel récursif}

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 ;

For i:=1 To nbd Do


Begin
For j:=1 To nDames Do
If ((T[j] = i) OR (Abs(T[j] - i) = Abs(j-nDames))) Then GoTo suivant ;
4INFINFRC0007  Page 28 
http://www.najah.com 

T[nDames]:= i ;
place_dame (T, ndames +1);
suivant : continue;
End;
END;

{ ********** Programme Principal *********** }


BEGIN
ClrScr ;
solution:= 0 ;
init (T, nbd);
place_dame (T,1);
WriteLn ('Nombre de solutions = ' , solution );
END.

4INFINFRC0007  Page 29 

También podría gustarte