Exercice 4

Transcription

Exercice 4
Introduction à l'informatique et à l'algorithmique
(Corrections d'exercices en Turbo-Pascal)
Bruno Warin
Avertissements
Ce document propose certaines corrections d'exercices du livre L'algorithmique :
votre passeport informatique pour la programmation. Ces corrections sont écrites
en Turbo Pscal version 6.0.
Attention l'ordre et la numérotation de la plupart des exercices ont été modifiées, ils
ne correspondent pas à ceux du livre. Un peu de recherche sera nécessaire ((-:
2
Correction des exercices du chapitre 4
A5.1. QUESTION DE COURS
Exercice 1
En fin d'exécution, nous devons obtenir l'état de la trace ci-dessous :
Valeurs en entrée : 6, 30, 15, 23, 15, 45
HH : 6, 23
MM : 30, 15
SS : 15, 45
Total : 23415, 60330
Total2 : 83745
Valeurs en sortie : 23415, 83745, "La différence de secondes est :", 60330
Exercice 2
Les déclarations omises sont :
Var Libel : chaîne de caractères
PrixHT : numérique
TVA : numérique
TTC : numérique
Msg1 : châine de caractères
Msg2 : chaîne de caractères
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
3
Exercice 3
En fin d'exécution, nous devons obtenir l'état de la trace ci-dessous :
Valeurs en entrée : "Une règle en bois", 16, 0.186
Libel : "Une règle en bois",
PrixHT: 16
TVA : 0.186
TTC : 18.976
Msg1 : "Une règle en bois coûte "
Msg2 : " francs."
Valeurs en sortie : "Une règle en bois coûte ", 18.976, " francs."
A5.2. EXERCICES AVEC DES VALEURS NUMERIQUES
Exercice 4
Program CERCLE;
{Calcul de la circonférence d'un cercle}
Uses Dos, Crt;
Var Diametre : real;
Circonference : real;
Begin
{Saisie du diamètre du cercle}
Writeln('Entrez le diamètre de votre cercle :');
Readln(Diametre);
{Calcul de la circonférence}
Circonference:=Diametre*3.14;
{Affichage de la circonférence}
Writeln('La circonférence est ',Circonference:5:3);
End.
Exercice 5
Program TROUPEAU;
{Calcul du prix d'un troupeau }
Uses Dos, Crt;
Var NbVaches, NbMoutons, Prix : real;
Begin
{Saisie du nombre de vaches et de moutons du troupeau}
Writeln('Entrez le nombre de vaches :');
Readln(NbVaches);
Writeln('Entrez le nombre de moutons :');
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
4
Readln(NbMoutons);
{Calcul du prix du troupeau}
Prix:=NbVaches*6000 + NbMoutons*2000;
{Affichage du prix du troupeau}
Writeln('Le prix du troupeau est de ',Prix:8:0, ' Francs !');
End.
Exercice 6
Program CALCUL_MOYENNE; {Calcul de la moyenne d'un étudiant}
Uses Dos, Crt;
Var NoteFrancais, NoteMathematique, NoteAnglais, Moyenne : real;
Begin
{Entrée des notes}
Writeln('Entrez la note de français :');
Readln(NoteFrancais);
Writeln('Entrez la note de mathematique :');
Readln(NoteMathematique);
Writeln('Entrez la note d''anglais :');
Readln(NoteAnglais);
{Calcul de la moyenne}
Moyenne:=(NoteFrancais*3 + NoteMathematique*7 + NoteAnglais)/11;
{Affichage de la moyenne}
Writeln('La moyenne est ',Moyenne:5:2);
End.
Exercice 7
Program CALCUL_PENALITE; {Calcul de pénalités pour retard de
paiements}
Uses Dos, Crt;
Var RedevanceInitiale : real;
Redevance1Mois, Redevance2Mois, Redevance3Mois : real;
Begin
{Entrée de la redevance initiale}
Writeln('Entrez la redevance initiale :');
Readln(RedevanceInitiale);
{Calcul des nouvelles redevances aprés retards de 1, 2 et 3 mois}
Redevance1Mois:=RedevanceInitiale*1.10;
Redevance2Mois:=Redevance1Mois*1.125;
Redevance3Mois:=Redevance2Mois*1.15;
{Affichage des redevances calculées}
Writeln('Après 1 mois de retard, vous devrez payer ',Redevance1Mois:10:5);
Writeln('Après 2 mois de retard, vous devrez payer ',Redevance2Mois:10:5);
Writeln('Après 3 mois de retard, vous devrez payer ',Redevance3Mois:10:5);
End.
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
5
Exercice 8
Program CALCUL_INTERET; {Calcul d'intérêts d'un placement bancaire}
Uses Dos, Crt;
Var MontantInitial, Somme1An, Somme2Ans, Somme3Ans : real;
Begin
{Entrée du montant initial}
Writeln('Entrez le montant initial :');
Readln(MontantInitial);
{Calcul des sommes disponibles au bout de 1, 2 et 3 ans}
Somme1An:=MontantInitial*1.036;
Somme2Ans:=Somme1An*1.054;
Somme3Ans:=Somme2Ans*1.072;
{Affichage des sommes disponibles}
Writeln('Capital disponible après 1 an : ',Somme1An:10:5);
Writeln('Capital disponible après 2 ans : ',Somme2Ans:10:5);
Writeln('Capital disponible après 3 ans : ',Somme3Ans:10:5);
End.
Exercice 9
Program CALCUL_VOITURE; {Calcul de la valeur vénale d'une voiture}
Uses Dos, Crt;
Var ValeurAchat, Valeur1An, Valeur2ans, Valeur3ans : real;
Begin
{Saisie de la valeur d'achat}
Writeln('Entrez la valeur d''achat de la voiture :');
Readln(ValeurAchat);
{Calcul des valeurs vénales au bout de 1, 2 et 3 ans d'ancienneté}
Valeur1An:=ValeurAchat*0.80;
Valeur2Ans:=Valeur1An*0.87;
Valeur3ans:=Valeur2Ans*0.93;
{Affichage des valeurs vénales}
Writeln('Valeur de la voiture au bout d''1 an : ',Valeur1An:10:5);
Writeln('Valeur de la voiture au bout de 2 ans : ',Valeur2Ans:10:5);
Writeln('Valeur de la voiture au bout de 3 ans : ',Valeur3Ans:10:5);
End.
Exercice 10
Program CALCUL_TRANSPORT; {Calcul de coûts de transport par air, mer
et fer}
Uses Dos, Crt;
Var Poids, Volume : real;
PrixParAir, PrixParMer, PrixParFer : real;
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
6
Begin
{Saisie du poids et du volume des marchandises à transporter}
Writeln('Entrez le poids de la marchandise à transporter (en kg) :');
Readln(Poids);
Writeln('Entrez le volume de la marchandise à transporter (en m3) :');
Readln(Volume);
{Calcul des coûts de transports}
PrixParAir:=Poids*0.5;
PrixParMer:=Volume*720;
PrixParFer:=Volume*34 + Poids*0.20;
{Affichage des coûts de transports}
Writeln('Le prix du transport par air est de : ',PrixParAir:8:2, ' Francs');
Writeln('Le prix du transport par mer est de : ',PrixParMer:8:2, ' Francs');
Writeln('Le prix du transport par fer est de : ',PrixParFer:8:2, ' Francs');
End.
Exercice 11
Program DECOMPOSITION;
{Décomposition de mètres carrés en
hectares, ares et centiares}
Uses Dos, Crt;
Var MetreCarre, Hectare, are, centiare : real;
Reste : real;
Begin
{Saisie de la surface en mètre carré}
Writeln('Entrez la surface en mètres carrés :');
Readln(MetreCarre);
{Calcul de la décomposition}
Hectare:=int(MetreCarre/10000);
Reste:=MetreCarre-Hectare*10000;
Are:=int(Reste/100);
Centiare:=Reste-Are*100;
{Affichage de la décomposition hectares, ares et centiares}
Writeln('La décomposition en hectare, ares et centiares donne : ');
Writeln(hectare:4:0, ' hectares ', are:2:0, ' ares et ', Centiare:2:0, ' centiares');
End.
Exercice 12
Program CALCUL_DIFFERENCE;
moments d'une journée}
Uses Dos, Crt;
Var Heure1, Minute1, Seconde1 : real;
Heure2, Minute2, Seconde2 : real;
Heure3, Minute3, Seconde3 : real;
Moment1, Moment2 : real;
Difference, Reste : real;
{Calcul de la différence entre deux
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
7
Begin
{Saisie du premier moment}
Writeln('Entrez les heures du premier moment :');
Readln(Heure1);
Writeln('Entrez les minutes du premier moment :');
Readln(Minute1);
Writeln('Entrez les secondes du premier moment :');
Readln(Seconde1);
{Saisie du second moment}
Writeln('Entrez les heures du second moment :');
Readln(Heure2);
Writeln('Entrez les minutes du second moment :');
Readln(Minute2);
Writeln('Entrez les secondes du second moment :');
Readln(Seconde2);
{Conversion en secondes}
Moment1:=Heure1*3600 + Minute1*60 + Seconde1;
Moment2:=Heure2*3600 + Minute2*60 + Seconde2;
{Calcul de la différence}
Difference:=Moment1 - Moment2;
{(Re)Conversion en heure, minute et seconde}
Heure3:=int(Difference/3600);
Reste:=Difference-Heure3*3600;
Minute3:=int(Reste/60);
Seconde3:=Reste - Minute3*60;
{Affichage du résultat}
Writeln('La différence entre les deux moments est : ');
Writeln(Heure3:4:0, ' heures ', Minute3:2:0, ' minutes et ', Seconde3:2:0, '
secondes');
End.
A5.3. EXERCICES AVEC DES CHAINES DE
CARACTERES
Exercice 13
Program PERMUT; {Permutation de la première et dernière lettre d'une
chaîne de caractères}
Uses Dos, Crt;
Var CH : string;
Debut, Milieu, Fin : string;
Begin
{Saisie de la chaîne à traiter}
Writeln('Entrez votre chaîne de caractères :');
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
8
Readln(CH);
{Calcul des composants de la chaîne après la permutation demandée}
Debut:=copy(Ch, 1, 1);
Milieu:=copy(Ch, 2, Length(Ch)-2);
Fin:=copy(ch, length(ch), 1);
{Construction et affichage de la chaîne souhaitée}
Writeln(Fin+Milieu+Debut);
Writeln('Appuyez sur une touche pour continuer');
Readln(CH);
End.
Exercice 14
Program TRANSFOM1;
{Transformation d'une chaîne de caractères}
Uses Dos, Crt;
Var Ch, Debut, Fin, Ch2: string;
N : integer;
Begin
{Saisie des données du problème}
Writeln('Entrez la chaîne à traiter :');
Readln(Ch);
Writeln('Entrez la position dans la chaîne :');
Readln(N);
{Construction de la chaîne demandée}
Debut:=Copy(ch,1,Length(Ch)-N);
Fin:=Copy(Ch,Length(Ch)-N+1,N);
Ch2:= Fin + Debut;
{Affichage de la chaîne demandée}
Writeln('on obtient :', Ch2);
End.
Exercice 15
Program TRANSFORM2; {Transformation d'une chaîne de caractères}
Uses Dos, Crt;
Var Ch, Debut, Fin, Ch2: string;
P, L : integer;
Begin
{Saisie des données du problème}
Writeln('Entrez la chaîne à traiter :');
Readln(Ch);
Writeln('Entrez la position dans la chaîne :');
Readln(P);
Writeln('Entrez la longueur à effacer :');
Readln(L);
{Construction de la chaîne demandée}
Debut:=Copy(ch,1,P);
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
9
Fin:=Copy( Ch, P+L+1, Length(Ch)-(P+L) );
Ch2:= Debut + Fin;
{Affichage de la chaîne demandée}
Writeln('On obtient :', Ch2);
End.
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
10
Annexe 6
Correction des exercices du chapitre 5
Exercice 1
On obtient les résultats suivants avec 3 chiffres après la virgule :
0, 0, 0 donne
"Toutes les valeurs sont admises !"
1, 0, 5 donne
"Aucune valeur n'est admise !"
2, 3, -6 donne 2.637 et 0.137
3, 4, 1 donne
-1 et -0.333
4, 7, -9 donne
-2.612 et 0.861
5, 2, 4 donne
"Aucune valeur n'est admise !"
Ces résultats peuvent être vérifiés à l'aide du programme PASCAL ci-après :
Program DEUG_DG;
{Programme de résolution d'une équation du
second degré}
Uses Dos, Crt;
Var A, B, C, D : real;
X1, X2 : real;
Begin
{Entrée des coefficients de l'équation}
Writeln('Entrez le premier nombre (coefficient A) :');
Readln(A);
Writeln('Entrez le second nombre (coefficient B) :');
Readln(B);
Writeln('Entrez le troisième nombre (coefficient C) :');
Readln(C);
{Calcul et sortie des solutions}
If A = 0 Then Begin
If B = 0 Then Begin
If C = 0 Then Begin
Writeln('Toutes les valeurs sont admises !');
End Else Begin
Writeln('Aucune valeur n''est admise !')
End
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
11
End Else Begin
X1:=-C/B;
Writeln('Seule la valeur ', X1:8:3, ' est admise !');
End
End Else Begin
D:=B*B - (4 * A * C);
If D>=0 Then Begin
If D=0 Then Begin
X1:=-B/(2*A);
Writeln('La valeur ', X1:8:3, ' est admise deux fois !');
End Else Begin
X1:=(-B-Sqrt(D)) / (2*A);
X2:=(-B+Sqrt(D)) / (2*A);
Writeln('Les valeurs ', X1:8:3, ' et ', X2:9:5, ' sont admises !');
End;
End Else Begin
Writeln('Aucune valeur réelle n''est admise !');
End;
End;
End.
Exercice 2
La première correction n'utilise que l'instruction If...Then. On remarquera que
les blocs d'instructions ne contenant qu'une seule instruction nous avons pu utilisé
la forme simplifiée de l'instruction If..Then, celle pour laquelle, on n'a pas besoin de
mettre des Begin...End :
Program GEL1;
{Calcul des liquides gelées à une température donnée.
Version 1}
Uses Dos, Crt;
Var Temperature : real;
Verdict : string;
Begin
{Entrée de la température}
Writeln('Entrez la température à traiter :');
Readln(Temperature);
{Calcul de la liste des liquides gelés}
Verdict:='';
If Temperature<=0 Then Verdict:=Verdict+'Eau gelée -';
If Temperature<=-3 Then Verdict:=Verdict+' Eau salée gelée -';
If Temperature<=-5 Then Verdict:=Verdict+' Fuel gelé -';
If Temperature<=-13 Then Verdict:=Verdict+' Ordinaire gelé -';
If Temperature<=-23 Then Verdict:=Verdict+' Super gelé -';
{Sortie de la liste des liquides gelées}
WriteLn('On obtient :', Verdict);
End.
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
12
La seconde correction utilise l'instruction If...Then...Else. Comme pour la
première correction, on remarquera que les blocs d'instructions ne contenant qu'une
seule instruction nous avons utilisé la forme simplifiée de l'instruction
If..Then...Else, celle pour laquelle, on n'a pas besoin de mettre des Begin...End :
Program GEL2;
{Calcul des liquides gelées à une température donnée.
Version 2}
Uses Dos, Crt;
Var Temperature : real;
Begin
{Entrée de la température}
Writeln('Entrez la température à traiter :');
Readln(Temperature);
{Détermination et sortie de la liste des liquides gelés}
If Temperature>0 Then
Writeln('Aucun liquide gelé !') {Rappel : pas de ; devant un Else}
Else If Temperature>-3 Then
WriteLn('Eau gelée')
Else If Temperature>-5 Then
WriteLn('Eau, Eau salée gelées')
Else If Temperature>-13 Then
WriteLn('Eau, Eau salée, Fuel gelés')
Else If Temperature>-23 Then
WriteLn('Eau, Eau salée, Fuel, Ordinaire gelés')
Else
WriteLn('Eau, Eau salée, Fuel, Ordinaire, Super gelés');
End.
En LAP, à l'aide de l'instruction Cas..De, il existe une troisième correction
élégante. Par contre, en PASCAL, vus les limitations portées par l'instruction
Case...Of, voir annexe 4, nous sommes obliger de "tricher" un peu comme le
montre la correction ci-après.
Program GEL3;
{Calcul des liquides gelées à une température donnée.
Version 3}
Uses Dos, Crt;
Var Temperature : real;
Begin
{Entrée de la température}
Writeln('Entrez la température à traiter :');
Readln(Temperature);
{Ajustement de la température entrée pour pouvoir la traiter par un Case Of}
If Temperature>0 Then Temperature:=1;
If Temperature<-23 Then Temperature:=-24;
{Détermination et sortie de la liste des liquides gelées}
Case Trunc(Temperature) Of
{Trunc convertir de real en integer}
1
: Writeln('Aucun liquide gelé');
0..-2
: WriteLn('Eau gelée');
-4..-3
: WriteLn('Eau, Eau salée gelées');
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
13
-12..-5 : WriteLn('Eau, Eau salée, Fuel gelés');
-22..-13 : WriteLn('Eau, Eau salée, Fuel, Ordinaire gelés');
-24..-23 : WriteLn('Eau, Eau salée, Fuel, Ordinaire, Super gelés');
End;
End.
Exercice 3
La première correction ci-après n'utilise que l'instruction If...Then.
Program MENTION1;
{Calcul de la mention d'un étudiant. Version 1}
Uses Dos, Crt;
Va Note1, Note2, Note3, Moyenne : real;
Begin
{Entrée des notes d'examens}
Writeln('Entrez la première note :');
Readln(Note1);
Writeln('Entrez la deuxième note :');
Readln(Note2);
Writeln('Entrez la deuxième note :');
Readln(Note3);
{Calcul de la moyenne}
Moyenne:=(Note1 + Note2 + Note3)/3;
{Détermination et sortie d la mention}
If Moyenne>=16 Then Writeln('Mention TRES BIEN');
If (Moyenne<16) and (Moyenne>=14) Then Writeln('Mention BIEN');
If (Moyenne<14) and (Moyenne>=12) Then Writeln('Mention ASSEZ BIEN');
If (Moyenne<12) and (Moyenne>=10) Then Writeln('Mention INSUFFISANT');
If (Moyenne<10) and (Moyenne>=5) Then Writeln('Mention INSUFFISANT');
If (Moyenne<5) Then Writeln('Mention TRES INSUFFISANT');
End.
La seconde correction n'utilise que l'instruction If..Then...Else et est à la fois
plus élégante et plus efficace en temps calcul.
Program MENTION2;
{Calcul de la mention d'un étudiant}
Uses Dos, Crt;
Var Note1, Note2, Note3, Moyenne : real;
Begin
{Entrée des notes d'examens}
Writeln('Entrez la première note :');
Readln(Note1);
Writeln('Entrez la deuxième note :');
Readln(Note2);
Writeln('Entrez la deuxième note :');
Readln(Note3);
{Calcul de la moyenne}
Moyenne:=(Note1 + Note2 + Note3)/3;
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
14
{Détermination et sortie de la mention}
If Moyenne>=16 Then Writeln('Mention TRES BIEN')
Else If Moyenne>=14 Then Writeln('Mention BIEN')
Else If Moyenne>=12 Then Writeln('Mention ASSEZ BIEN')
Else If Moyenne>=10 Then Writeln('Mention INSUFFISANT')
Else If Moyenne>=5 Then Writeln('Mention INSUFFISANT')
Else Writeln('Mention TRES INSUFFISANT');
End.
Exercice 4
Program CLASSIFICATION;
{Classification d'un caractère}
Uses Dos, Crt;
Var Ch : string;
Begin
{Entrée du caractère à classer}
Writeln('Entrez un caractère :');
Readln(Ch);
{Analyse du caractère entré et sortie de la classification}
If (Ch>='0') and (Ch<='9') Then
Writeln('CHIFFRE')
Else
If ( (Ch>='A') and (Ch<='Z') ) or ( (Ch>='a') and (Ch<='z') ) Then
Writeln('LETTRE')
Else
Writeln('AUTRE');
End.
Exercice 5
Program CONVERSION;
{Conversion d'un caractère en équivalent
numérique}
Uses Dos, Crt;
Var Ch : string;
Valeur : integer;
Begin
{Entrée du caractère à traiter}
Writeln('Entrez un caractère :');
Readln(Ch);
{Analyse et conversion du caractère entré}
If Not ( (Ch>='0') and (Ch<='9') ) Then
Writeln('N''est pas un chiffre')
Else Begin
If Ch='0' Then Valeur:=0
Else If Ch='1' Then Valeur:=1
Else If Ch='2' Then Valeur:=2
Else If Ch='3' Then Valeur:=3
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
15
Else If Ch='4' Then Valeur:=4
Else If Ch='5' Then Valeur:=5
Else If Ch='6' Then Valeur:=6
Else If Ch='7' Then Valeur:=7
Else If Ch='8' Then Valeur:=8
Else if Ch='9' Then Valeur:=9;
{Calcul avec la conversion}
Valeur:=Valeur*3;
{Sortie du résultat}
Writeln('Chiffre ',Valeur:2);
End;
End.
Exercice 6
Program FIN_CHAINE;
{Isolement d'une fin de chaîne}
Uses Dos, Crt;
Var Ch, Resultat : string;
N : integer;
Begin
{Entrée des des données}
Writeln('Entrez votre chaîne :');
Readln(Ch);
Writeln('Entrez votre position :');
Readln(N);
{Analyse des données et sortie du résultat}
If N > Length(Ch) Then
Writeln('Opération impossible : chaîne trop courte')
Else Begin
Resultat:=Copy(Ch, Length(Ch)-N+1, N);
Writeln('On obtient : ',Resultat);
End;
End.
Exercice 7
Program COMPARAISON;
{Comparaison de deux chaînes de
caractères}
Uses Dos, Crt;
Var Nom1, Nom2 : string;
Begin
{Entrée des noms}
Writeln('Entrez le premier nom :');
Readln(Nom1);
Writeln('Entrez le deuxième nom :');
Readln(Nom2);
{Sortie des noms par ordre de tri}
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
16
If Nom1 > Nom2 Then
Writeln(Nom2, ' ', Nom1)
Else
Writeln(Nom1, ' ', Nom2);
End.
Exercice 8
La première correction est un exercice de style, elle procède en testant les six
cas possibles.
Program TRI1;
{Tri de 3 nombres. Version 1}
Uses Dos, Crt;
Var N1, N2, N3 : Real;
Begin
{Entrée des trois nombres à trier}
Writeln('Entrez le premier nombre :');
Readln(N1);
Writeln('Entrez le deuxième nombre :');
Readln(N2);
Writeln('Entrez le troisième nombre :');
Readln(N3);
{Tests de tous les cas possibles et sortie des résultats}
If N1 > N2 Then
If N1 > N3 Then
If N2 > N3 Then
Writeln(N3:5:2, ' ', N2:5:2, ' ', N1:5:2)
Else
Writeln(N2:5:2, ' ', N3:5:2, ' ', N1:5:2)
Else
Writeln(N2:5:2, ' ', N1:5:2, ' ', N3:5:2)
Else {donc N2 >= N1}
If N2 > N3 Then
If N1 > N3 Then
Writeln(N3:5:2, ' ', N1:5:2, ' ', N1:5:2)
Else
Writeln(N1:5:2, ' ', N3:5:2, ' ', N2:5:2)
Else
Writeln(N1:5:2, ' ', N2:5:2, ' ', N3:5:2);
End.
La seconde correction s'appuie sur une autre stratégie : elle teste les nombres
deux à deux et lorsque l'ordre N1, N2, N3 n'est pas respecté, elle permute les
contenus des variables en cause. On obtient :
Program TRI2;
{Tri de 3 nombres par sélection-permutation}
Uses Dos, Crt;
Var N1, N2, N3, Temporaire : Real;
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
17
Begin
(* Entrée des trois nombres à trier}
Writeln('Entrez le premier nombre :');
Readln(N1);
Writeln('Entrez le deuxième nombre :');
Readln(N2);
Writeln('Entrez le troisième nombre :');
Readln(N3);
{Mise dans N1 du plus petit des 3 nombres}
If N1>N2 Then Begin {échange}
Temporaire:=N1;
N1:=N2;
N2:=Temporaire;
End;
If N1>N3 Then Begin
Temporaire:=N1;
N1:=N3;
N3:=Temporaire;
End;
{Mise dans N2 du plus petit des 2 nombres entre N2 et N3}
If N2>N3 Then Begin
Temporaire:=N2;
N2:=N3;
N3:=Temporaire;
End;
{Sortie du résultat du tri}
Writeln(N1:5:2, ' ', N2:5:2, ' ', N3:5:2);
End.
Exercice 9
Question 1
On obtient le tableau suivant :
Tarifs DUFER
Tarifs DELAPOINTE
Moins de Les kilos 10 Les autres Moins de 5 Les kilos 5
10 kilos.
à 50.
kilos.
kilos
à 100.
Clous de 10
15
13.95
12
16
14.40
mm.
Clous de 30
20
18.6
16
19
17.10
mm.
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
Les autres
kilos.
13.6
16.15
18
Question 2
4 kilos de clous de 10 mm chez Monsieur DUFER coûtent 4 x 15 soient 60
francs.
75 kilos de clous de 30mm chez Monsieur DUFER coûtent (9 x 20) + (41 x
18.6) + (25x16) soient 1 342,60 francs.
4 kilos de clous de 10 mm chez Monsieur DELAPOINTE coûtent 4 x 16 soient
64 francs.
75 kilos de clous de 30 mm chez Monsieur DELAPOINTE coûtent (4 x 19) +
(71 x 17,10)= soient 1 290,10 francs.
Question 3
4 kilos de clous de 10 mm chez Monsieur DUFER coûtent 60 francs et 63 kilos
de clous de 30mm chez Monsieur DUFER coûtent 1 150,60 francs. La commande
passée chez Monsieur DUFER s'élèverait à donc 1 210,60 francs.
Tandis que 4 kilos de clous de 10 mm chez Monsieur DELAPOINTE coûtent
64 francs et 63 kilos de clous de 30 mm chez Monsieur DELAPOINTE coûtent
1 084,90 francs. La commande passée chez Monsieur DELAPOINTE s'élèverait à
donc 1 149 francs.
Pour cette première commande Monsieur DELAVIS passera commande chez
Monsieur DELAPOINTE.
118 kilos de clous de 10 mm chez Monsieur DUFER coûtent 1 509 francs et 63
kilos de clous de 30mm chez Monsieur DUFER coûtent 9 132 francs. La
commande passée chez Monsieur DUFER s'élèverait à 10 641 francs.
Tandis que 118 kilos de clous de 10 mm chez Monsieur DELAPOINTE coûtent
1 691 francs et 563 kilos de clous de 30 mm chez Monsieur DELAPOINTE coûtent
9 243 francs. La commande passée chez Monsieur DELAPOINTE s'élèverait à
10 934 francs.
Pour cette seconde commande Monsieur DELAVIS passera commande chez
Monsieur DUFER.
Question 4
Program COMMANDE;
{Détermination du coût de commandes de
clous}
Uses Dos, Crt;
Var Qte10mm, Qte30mm : Real;
Prix10mmDUFER, Prix30mmDUFER : real;
Prix10mmDELAPOINTE, Prix30mmDELAPOINTE : real;
TotalDUFER, TotalDELAPOINTE : real;
Begin
{Entrée des caractéristiques de la commande}
Writeln('Entrez le poids de clous de 10mm à commander :');
Readln(Qte10mm);
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
19
Writeln('Entrez le poids de clous de 30mm à commander :');
Readln(Qte30mm);
{Calcul des prix chez Monsieur DUFER}
{Calcul pour les clous de 10mm}
If Qte10mm<=9 Then
Prix10mmDUFER:=Qte10mm*15
Else If Qte10mm<=50 Then
Prix10mmDUFER:=9*15 + (Qte10mm-9)*13.95
Else
Prix10mmDUFER:=9*15 + (41*13.95) + (Qte10mm-50)*12;
{Calcul pour les clous de 30mm}
If Qte30mm<=9 Then
Prix30mmDUFER:=Qte30mm*20
Else If Qte30mm<=50 Then
Prix30mmDUFER:=9*20 + (Qte30mm-9)*18.6
Else
Prix30mmDUFER:=9*20 + (41*18.6) + (Qte30mm-50)*16;
{Calcul des prix chez Monsieur DELAPOINTE}
{Calcul pour les clous de 10mm}
If Qte10mm<=4 Then
Prix10mmDELAPOINTE:=Qte10mm*16
Else If Qte10mm<=100 Then
Prix10mmDELAPOINTE:=4*16 + (Qte10mm-4)*14.40
Else
Prix10mmDELAPOINTE:=4*16 + (96*14.40) + (Qte10mm-100)*13.60;
{Calcul pour les clous de 30mm}
If Qte30mm<=4 Then
Prix30mmDELAPOINTE:=Qte30mm*19
Else If Qte30mm<=100 Then
Prix30mmDELAPOINTE:=4*19 + (Qte30mm-4)*17.10
Else Prix30mmDELAPOINTE:=4*19 + (96*17.6) + (Qte30mm-100)*16.15;
{Verdict}
TotalDUFER:=Prix10mmDUFER + Prix30mmDUFER;
TotalDELAPOINTE:=Prix10mmDELAPOINTE + Prix30mmDELAPOINTE;
If TotalDUFER >= TotalDELAPOINTE Then Begin
Writeln('Il est préférable de passer la commande ci-dessous chez Monsieur ',
'DUFER');
Writeln('10mm : ',Qte10mm:5:0,' kilos pour un montant de ',
Prix10mmDUFER:5:0,' francs');
Writeln('30mm : ',Qte30mm:5:0,' kilos pour un montant de ',
Prix30mmDUFER:5:0,' francs');
End Else Begin
Writeln('Il est préférable de passer la commande ci-dessous chez Monsieur ',
'DELAPOINTE');
Writeln('10mm : ',Qte10mm:5:0,' kilos pour un montant de ',
Prix10mmDELAPOINTE:5:0,' francs');
Writeln('30mm : ',Qte30mm:5:0,' kilos pour un montant de ',
Prix30mmDELAPOINTE:5:0,' francs');
End;
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
20
End.
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
21
Annexe 7
Correction des exercices du chapitre 6
FEUILLE D'EXERCICES NUMÉRO 1
Exercice 1
Le programme de la figure A7.1 réalise le traitement demandé. Il est composé
de trois parties :
1. L'entrée du nombre limite dans la variable N.
2. L'initialisation à 1 du compteur de boucle I.
3. La sortie des nombres demandée à l'aide d'une boucle Repeat.
Program SUITE;
{Sortie d'une suite de nombres}
Uses Dos, Crt;
Var N, I : integer;
Begin
{Entrée dans la variable N du nombre limite}
Writeln('Entrez votre nombre (>=1) :');
Readln(N);
{Initialisation du compteur de boucle}
I:=1;
{Boucle de sortie des nombres de 1 à N}
Repeat
Writeln(I:3);
I:=I+1;
Until I>N;
End.
Figure A7.1. Sortie d'une suite de nombres
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
22
La boucle Repeat est une boucle avec test d'arrêt d'après compteur, dans
laquelle le compteur est la variable I. Au cours de cette boucle la variable I variera
de 1 à N et s'arrêtera quand I deviendra strictement supérieur à N. Pour chaque
valeur de I, une instruction Writeln est exécutée.
A titre d'exercice supplémentaire, le lecteur est invité à réécrire ce programme
en remplaçant l'instruction Repeat par une instruction While ou For
Exercice 2
Le programme de la figure A7.2 réalise le traitement demandé. Il est composé
de trois parties :
1. L'initialisation à zéro des deux compteurs NbPositif et NbNegatif.
2. La saisie des nombres et le comptage demandé à l'aide d'une boucle Repeat.
3. La sortie du nombre de nombres positifs et négatifs trouvés.
Program POSITIF;
{Calcul du nombre de nombres positifs et négatifs
d'une liste de nombres terminée par zéro}
Uses Dos, Crt;
Var N, NbPositif, NbNegatif : integer;
Begin
{Initialisations des compteurs}
NbPositif:=0;
NbNegatif:=0;
{Boucle de saisie des nombres et de comptage des positifs et négatifs}
Repeat
{Entrée d'un nombre}
Writeln('Entrez votre nombre :');
Readln(N);
{Analyse du nombre entré}
If N>0 Then
NbPositif:=NbPositif+1
Else If N<0 Then
NbNegatif:=NbNegatif+1;
Until N=0;
{Sortie du résultat}
Writeln(NbPositif:3,' ',NbNegatif:3);
End.
Figure A7.2. Calcul du nombre de nombres positifs et négatifs d'une liste de nombres terminée par
zéro
Au cours de l'exécution du programme la variable NbPositif mémorisera le
nombre de nombres positifs entrés par l'utilisateur depuis le début et NbNegatif
mémorise le nombre de nombres négatifs entrés par l'utilisateur depuis le début.
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
23
C'est pourquoi, en début d'exécution, elles sont initialisées toutes les deux à zéro :
aucun nombre n'ayant encore été entré.
La boucle de la deuxième partie est programmée avec une instruction Repeat
qui à chaque tour de boucle entre une nouvelle valeur et met à jour, si nécessaire,
les compteurs NbPositif et NbNegatif. L'arrêt de la boucle, au bon moment, est
garanti par son test d'arrêt qui s'assure de la présence de la valeur zéro dans la
variable N.
A titre d'exercice supplémentaire, le lecteur est invité à réécrire ce programme
en utilisant l'instruction While au lieu de l'instruction Repeat. Il pourra en profiter
pour concevoir une boucle avec test d'arrêt avec sentinelle comme vu au paragraphe
6.3.2.
Exercice 3
Le programme de la figure A7.3 réalise le traitement demandé. Il est composé
de quatre parties :
1. L'entrée de la chaîne à traiter. Celle pour laquelle il faut déterminer si oui ou
non, elle possède un caractère numérique. Cette chaîne est mémorisée dans la
variable Ch.
2. L'initialisation des variables Present et Pos.
3. Le parcours, caractère par caractère, de la chaîne entrée à l'aide d'une boucle
While.
4. Le verdict, c'est-à-dire la sortie du message "OUI" ou "NON".
Les initialisations consistent à initialiser les variables Present et Pos. La
variable Present est une sentinelle, elle est initialisée à la valeur "FAUX" et recevra
la valeur "VRAI" dès qu'un caractère numérique aura été détecté dans Ch. En début
d'exécution aucun caractère de Ch n'ayant été testé, il est logique d'initialiser
Present à "FAUX". Pos est la variable de parcours de la chaîne de caractères Ch.
Pos représente aussi le nombre de caractères déjà traités. En début d'exécution,
aucun caractère n'ayant été traité, il est logique d'initialiser Pos à zéro.
Le parcours, caractère par caractère, de la chaîne Ch est programmé avec une
boucle While. La variable de parcours est la variable Pos qui varie de 0 à Long(Ch).
Pour chaque valeur de Pos différente de zéro, le Posème caractère de la chaîne Ch est
isolé dans la variable Car grâce à l'instruction Car:=SChain(Ch, Pos, 1). Ensuite,
le test (Car>='0') and (Car<='9') permet de détecter la présence d'un caractère
numérique. De plus, le lecteur aura remarqué que le test d'arrêt de la boucle s'assure
que la variable Present ne contient pas la valeur 'VRAI'. En effet, dès qu'un
caractère numérique a été détecté dans Ch, il est inutile de poursuivre le parcours,
nous avons la réponse demandée.
A titre d'exercice supplémentaire, le lecteur est invité à réécrire ce programme
en utilisant l'instruction Repeat au lieu de l'instruction While. Il pourra en profiter
pour concevoir une boucle avec test d'arrêt avec deux sentinelles comme vu au
paragraphe 6.3.3. La dernière ligne de cette boucle pourrait être Until
(Present="VRAI") or (Fini="VRAI");
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
24
Program DETECT_NUMERIQUE;
{Recherche d'un caractère
numérique dans une chaîne de caractères}
Uses Dos, Crt;
Var Ch, Present, Car : string;
Pos : integer;
Begin
{Entrée de la chaîne à traiter}
Writeln('Entrez votre chaîne de caractères :');
Readln(Ch);
{Initialisations}
Present:='FAUX';
Pos:=0;
{Boucle de recherche d'un caractère numérique dans la chaîne Ch}
While (Present='FAUX') and (Pos<Length(Ch)) Do Begin
Pos:=Pos+1;
{Isolement du caractère courant}
Car:=Copy(Ch, Pos, 1);
{Test de la numéricité du caractère courant}
If (Car>='0') and (Car<='9') Then
Present:='VRAI'
End; {Fin du While}
{Verdict}
If Present='VRAI' Then
Writeln('OUI')
Else
Writeln('NON');
End.
Figure A7.3. Recherche d'un caractère numérique dans une chaîne de caractères
Exercice 4
Le programme de la figure A7.4 réalise le traitement demandé. Il est composé
de quatre parties :
1. L'Entrée du premier nombre des 7 nombres à traiter.
2. L'initialisation des variables PlusPetit et PlusGrand.
3. La saisie et l'analyse des 6 nombres restant à traiter à l'aide d'une boucle For.
4. La sortie du résultat demandé : le plus petit et le plus grand des 7 nombres
entrés.
Les deux premières parties permettent de traiter à part le cas du premier nombre
entré. Pour bien les comprendre, il faut savoir que dans ce programme PlusPetit et
PlusGrand sont deux variables qui ont pour vocation de mémoriser,
respectivement, le plus petit des nombres déjà entrés et le plus grand des nombres
déjà entrés. Le premier nombre entré par le programme est, par la force des choses,
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
25
à la fois le plus grand et le plus petit des nombres déjà entrés, le programme à
raison d'initialiser les variables PlusPetit et plusGrand avec celui-ci.
La troisième partie est la partie principale du programme, elle est constituée
d'une boucle For qui va permettre d'entrer le nombre voulu de nombres, ici 6
puisque le premier a été entré hors de la boucle. A chaque tour de boucle , un
nombre est entré et alors, si nécessaire, les variables PlusPetit et PlusGrand sont
mises à jour.
Program EXTREMES;
{Recherche du plus petit et du plus grand nombre
dans une liste de nombres}
Uses Dos, Crt;
Var N, PlusPetit, PlusGrand : real;
I : integer;
Begin
{Traitement à part du premier nombre}
Writeln('Entrez le premier nombre :');
Readln(N);
{Le premier nombre entré est forcément le plus petit et le plus grand des
nombres entrés jusqu'à présent}
PlusPetit:=N;
PlusGrand:=N;
{Boucle de saisie et détection}
For i:=2 to 7 DO begin
{Entrée du nombre suivant}
Writeln('Entrez le nombre numéro ', I:2, ' :');
Readln(N);
{Analyse de dernier nombre entré}
If N>PlusGrand Then
PlusGrand:=N
Else If N<PlusPetit Then
PlusPetit:=N;
End; {Fin du For}
{Sortie du Résultat}
Writeln(PlusPetit:8:2,' ',PlusGrand:8:2);
End.
Figure A7.4. Recherche du plus petit et du plus grand nombre dans une liste de nombres
Remarque : nous avons vu que le premier nombre est traité à part, hors de la
boucle. On est bien entendu tenté de traiter le cas du premier nombre dans la boucle
en initialisant les variables PlusPetit et PlusGrand avec la valeur zéro. Mais alors il
existe deux cas pour lesquels le programme délivrera un résultat incorrect. Le
premier cas est celui où les 7 nombres entrés sont tous strictement négatifs : le
programme renverra zéro comme plus grand nombre, ce qui est faux ! Le second
cas est celui où les nombres sont strictement positifs, le programme renverra zéro
comme plus petit nombre, ce qui est également faux. A moins de disposer d'une
fonction qui renvoie la plus grande et la plus petite des valeurs numériques
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
26
disponibles, comme en COBOL avec les fonctions Low-Value et High-Value, pour
obtenir un programme élégant et qui renvoie dans tous les cas les bonnes valeurs, il
est conseillé, de traiter le premier nombre à part, hors de la boucle.
A titre d'exercice supplémentaire, le lecteur est invité à réécrire ce programme
en remplaçant l'instruction For par une instruction While ou Repeat.
Exercice 5
Le programme de la figure A7.5 réalise le traitement demandé. Il est composé
de trois parties :
1. L'Entrée du nombre à décomposer en facteurs premiers.
2. L'initialisation de la variable Pos à la valeur 2.
3. La décomposition proprement dite à l'aide d'une boucle While.
Le principe général de la boucle est diviser successivement le nombre entré
avec tous les nombres et de s'arrêter lorsque, à force de division, on obtient le
nombre 1. A chaque fois qu'une division a été effectuée le diviseur de celle-ci, qui
est un nombre premier (cf. explications plus loin), est sorti. En fin de boucle, on
obtient bien en valeurs en sortie, toutes les occurrences de nombres premiers qui
forment la décomposition en facteurs premiers du nombre entré.
Program FACTEUR_PREMIER;
{Décomposition d'un nombre en
facteurs premiers}
Uses Dos, Crt;
Var N, RacineN, Pos : real;
Begin
{Entrée du nombre à décomposer}
Writeln('Entrez le nombre à décomposer :');
Readln(N);
{2 est le premier nombre premier}
Pos:=2;
{Boucle d'élaboration de la décomposition}
While N<>1 Do Begin
{Test de divisibilité}
If N=Int(N/Pos)*Pos Then Begin
{Pos est donc un diviseur premier pour N : on le sort}
Writeln(Pos:3:0);
N:=N/Pos;
End Else
Pos:=Pos+1;
End; {Fin du While}
End.
Figure A7.5. Décomposition d'un nombre en facteur premier
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
27
Comme il n'existe pas de fonction qui renvoie la liste des nombres premiers, la
boucle de décomposition va faire prendre à Pos toutes les valeurs en séquence : 2,
3, 4, 5, 6, ... et essaiera donc de diviser notre nombre avec des nombres non
premiers. Mais ce n'est pas grave, car pour chacun de ces nombres non premiers le
test de divisibilité échouera forcément. En effet si Pos est un tel nombre non
premier, il ne pourra diviser N, car dans les tours de boucle précédents ce nombre
N aura été divisé par chacun des nombres premiers entrant dans la décomposition
en facteurs premiers de Pos !
Le programme de décomposition d'un nombre en facteurs premiers de la figure
A7.5 peut être améliorée. En effet, lorsque Pos sera strictement supérieur à la
racine carrée du nombre N en cours, alors on pourra affirmer qu'il n'existe pas de
N1 différent de N tel que N1 soit à la fois supérieur à Sqrt(N) et à la fois un diviseur
de N. Ou plus simplement cela veut dire que soit il n'existe plus de diviseur premier
supérieur ou égal à Pos pour N; soit N est un nombre premier, le dernier de la
décomposition en facteurs premiers du nombre initial. On peut donc modifier le
test d'arrêt de la boucle en (Pos<=Sqrt(N) and (N<>1).
Program FACTEUR_PREMIER2;
{Décomposition d'un nombre en
facteurs premiers}
Uses Dos, Crt;
Var N, RacineN, Pos : real;
Begin
{Entrée du nombre à décomposer}
Writeln('Entrez le nombre à décomposer :');
Readln(N);
{2 est le premier nombre premier}
Pos:=2;
RacineN:=Sqrt(N); {Sqrt(N) renvoi la racine carré de N}
{Boucle d'élaboration de la décomposition}
While (Pos<=RacineN) ou (N<>1) Do Begin
{Test de divisibilité}
If N=Int(N/Pos)*Pos Then Begin
{Pos est donc un diviseur premier pour N : on le sort}
Writeln(Pos:3:0);
N:=N/Pos;
End Else
Pos:=Pos+1;
End; {Fin du While}
{Cas de l'arrêt de la boucle par Pos<=RacineN)}
If N<>1 Then
WriteLn(N:3:0);
End.
Figure A7.6. Amélioration pragmatique de la décomposition d'un nombre en facteur premier
Cependant, comme la fonction Sqrt est une fonction qui coûte assez cher en
temps calcul, nous avons choisi une solution intermédiaire, qui consiste à
mémoriser dans la variable RacineN, la racine carrée du nombre initial et à
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
28
continuer la boucle tant que (Pos<=RacineN) and (N<>1). Ce faisant le
programme ne fait appel qu'une seul fois à la fonction Sqrt(). Nous obtenons alors
le programme de la figure A7.6.
Exercice 6
Question 1
Le programme de la figure A7.7 réalise le traitement demandé. Il est composé
de quatre parties :
1. L'entrée du nombre pour lequel nous allons calculer le carré.
2. L'initialisation des variables Impair et Somme.
3. Le calcul du carré par la méthode proposée à l'aide d'une boucle For.
4. La sortie du résultat demandé, c'est-à-dire le carré du nombre entré.
La troisième partie est la partie principale du programme, elle est constituée
d'une boucle For qui va permettre de générer un à un, dans la variable Impair, les N
premiers nombres impairs : un nombre impair à chaque tour de boucle. A chaque
génération d'un nombre impair celui-ci est additionné dans la variable Somme. En
fin d'exécution de la boucle, Somme contient la somme de N premiers nombres
impairs, et par voie de conséquence N au carré.
Program CALCUL_CARRE;
{ Calcul du carré d'un nombre sans faire
de multiplication}
Uses Dos, Crt;
Var N, Impair, Somme, I : integer;
Begin
{Entrée du nombre}
Writeln('Entrez votre nombre :');
Readln(N);
{Initialisations }
Impair:=1;
Somme:=0;
{Boucle d'addition des N premiers nombres impairs}
For i:=1 To N Do Begin
{Addition du nombre impair courant}
Somme:=Somme+Impair;
{Passage au nombre impair suivant}
Impair:=Impair+2;
End;
{Sortie du résultat}
Writeln(Somme:5);
End.
Figure A7.7. Calcul original du carré d'un nombre sans faire de multiplication
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
29
A titre d'exercice supplémentaire, le lecteur est invité à réécrire ce programme
en remplaçant l'instruction For par une instruction While ou Repeat.
Question 2
Le programme souhaité est identique à ceci près qu'il faut mettre l'instruction
Writeln(Somme:5) à l'intérieur de la boucle. En effet, en fin de chaque tour de
boucle nous avons l'assertion suivante {Somme contient la somme des I premiers
nombres impairs}.
FEUILLE D'EXERCICES NUMÉRO 2
Exercice 1
Le programme de la figure A7.8 réalise le traitement demandé. Il est composé
de quatre parties :
. L'entrée du nombre limite dans la variable N.
. L'initialisation des variables I et Somme.
. Le calcul de la somme des nombres de 1 à N à l'aide d'une boucle While.
. La sortie du résultat calculé.
Le calcul de la somme demandée est réalisé par une boucle avec test d'arrêt
d'après compteur, dans laquelle I est le compteur. Au cours de cette boucle I
prendra successivement les valeurs 1, 2, ... N. Pour chacune de ses valeurs
l'instruction Somme:=Somme+I est exécutée. En fin de boucle, la variable Somme,
initialisée à zéro, contiendra bien la somme des N premiers entiers.
Remarque : il s'agit ici d'un exercice d'algorithmique sur les boucles, car la
somme des N premiers nombres peut être calculée sans utiliser de boucle, par la
formule (N+1)*N/2. Ainsi la somme des 10 premiers nombres est égale à 11*10/2
soit 55.
Program SOMME;
{Calcul de la somme des premiers nombres}
Uses Dos, Crt;
Var N, I, Somme : integer;
Begin
{Entrée du nombre N, limite de la somme}
Writeln('Entrez votre nombre (>=1) :');
Readln(N);
{Initialisations}
I:=1;
Somme:=0;
{Boucle de sommation des nombres de 1 à N}
While I<=N Do Begin
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
30
{Addition du nombre entier courant}
Somme:=Somme+I;
{Passage au nombre entier suivant}
I:=I+1;
End; {Fin du While}
{Sortie du résultat}
Writeln(Somme:5);
End.
Figure A7.8. Calcul de la somme des N premiers nombres
Exercice 2
Le programme de la figure A7.9 réalise le traitement demandé. Il est composé
de deux parties :
1. L'entrée de la chaîne à décomposer dans la variable Ch.
2. La décomposition; lettre par lettre, de Ch à l'aide d'une boucle For.
Cette dernière partie est la partie principale du programme, elle est constituée
d'une boucle avec test d'arrêt d'après compteur, dans laquelle le compteur est la
variable I. Au cours de cette boucle la variable I variera de 1 à N. Pour chaque
valeur de I, une instruction Writeln(Copy(Ch, Pos,1)) est exécutée. La sélection
d'un caractère dans une chaîne de caractère s'opère en utilisant la fonction Schain et
spécifiant une valeur 1 comme longueur de la sous-chaîne à isoler.
A titre d'exercice supplémentaire, le lecteur est invité à réécrire ce programme
en remplaçant l'instruction For par une instruction Repeat ou While.
Program LETTRE_A_LETTRE;
{Découpage d'une chaîne de caractères}
Uses Dos, Crt;
Var Ch : string;
Pos : integer;
Begin
{Entrée de la chaîne à traiter}
Writeln('Entrez votre chaîne de caractères :');
Readln(Ch);
{Boucle de découpage de la chaîne entrée}
For Pos:=1 to Length(Ch) do Begin
Writeln(Copy(Ch,Pos,1));
End;
End.
Figure A7.9. Décomposition d'une chaîne de caractères
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
31
Exercice 3
Le programme de la figure A7.10 réalise le traitement demandé. Il est composé
de deux parties :
1. L'entrée du nombre limite dans la variable N.
2. La sortie de la suite des nombres demandés à l'aide d'une boucle Repeat.
Cette dernière partie est la partie principale du programme, elle est constituée
d'une boucle avec test d'arrêt d'après compteur, dans laquelle le compteur est la
variable N qui varie de -10 en -10 jusqu'à devenir inférieur ou égal à 0. A chaque
tour de boucle, l'instruction WriteLn(N:3) est exécutée. A noter que comme
l'énoncé pose que le nombre entrée doit être strictement supérieur à zéro et que
comme le test d'arrêt se trouve juste après la décrémentation N:=N-10, la valeur
zéro ne sera jamais sortie.
A titre d'exercice supplémentaire, le lecteur est invité à réécrire ce programme
en remplaçant l'instruction Repeat par une instruction While ou For.
Program TousLes10;
{Sortie de nombres de 10 en 10}
Uses Dos, Crt;
Var N : integer;
Begin
{Entrée du nombre limite de la sortie}
Writeln('Entrez votre nombre :');
Readln(N);
{Sortie de la suite de nombres demandée}
Repeat
{Sortie du nombre courant}
Writeln(N:3);
{Passage au nombre 'suivant'}
N:=N-10;
Until N<=0;
End.
Figure A7.10. Sortie de nombres de 10 en 10
Exercice 4
Le programme de la figure A7.11 réalise le traitement demandé. Il est composé
de quatre parties :
1. L'entrée des deux chaînes à traiter. Celles pour lesquelles il faut décider si oui
ou non, elles sont anagrammes l'une de l'autre. Les deux chaînes sont
mémorisées respectivement dans les variable Ch1 et Ch2.
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
32
2. L'initialisation de la variable Anagramme et la prise en compte du cas où les
chaîne Ch1 et Ch2 sont de longueur différentes. En effet, elles ne peuvent, dans
ce cas, être anagramme l'une de l'autre.
3. Le parcours, caractère par caractère, de la première chaîne, Ch1, caractère par
caractère à l'aide d'une boucle While. Cette boucle contient en elle une autre
boucle.
4. Le verdict, c'est-à-dire la sortie du message 'OUI' si Ch1 et Ch2 sont
anagrammes l'une de l'autre ou le message 'NON' dans le cas contraire.
La variable Anagramme est une sentinelle. Le programme se contraint à ne lui
affecter que deux valeurs possibles : 'VRAI' ou 'FAUX'. Au départ si les deux
chaînes Ch1 et Ch2 sont de longueurs différentes alors Anagramme est mis à
'FAUX' car Ch1 et Ch2 ne peuvent être, dans ce cas, anagrammes l'une de l'autre :
l'affaire est réglée. Dans le cas contraire Anagramme est mis à 'VRAI'. Ensuite la
vocation de la variable Anagramme est d'être mis à 'FAUX' dès que le programme
rencontre une occurrence de caractère de Ch1 qui ne se trouve pas dans Ch2.
La partie principale de ce programme est la troisième partie. Elle est constituée
de deux boucles imbriquées l'une dans l'autre. La boucle externe permet de
parcourir la première chaîne Ch1, caractère par caractère. Chaque caractère de Ch1
est isolé dans la variable de travail Car. La boucle interne parcourt alors la seconde
chaîne, Ch2, pour détecter si le caractère mémorisée dans Car s'y trouve. Dans le
cas où il ne s'y trouve pas alors Anagramme est mis à 'FAUX' car à l'évidence Ch1
et Ch2 ne sont pas anagrammes l'une de l'autre. Dans le cas contraire, l'occurrence
du caractère de Ch2 identique à Car est supprimée de la chaîne Ch2 par l'exécution
de l'instruction Ch2:=Copy(Ch2, 1, Pos2-1)+Copy(Ch2, Pos2+1, Length(Ch2)Pos2).
A titre d'exercice supplémentaire, le lecteur est invité à transformer les deux
boucles de cet algorithme en boucle avec deux sentinelles. Il pourra par exemple
introduire une sentinelle Fini1 pour la boucle externe et une sentinelle Fini2 pour la
seconde boucle. Il peut être intéressant de programmer cette exercice à l'aide d'une
seule boucle, c'est-à-dire sans utiliser de boucles imbriquées. A noter que dans tous
les cas l'instruction PASCAL Ch2:=Copy(Ch2, 1, Pos2-1)+Copy(Ch2, Pos2+1,
Length(Ch2)-Pos2) s'exécute sans problème alors que son équivalent LAP, encore
plus rigoureux, doit provoquer une erreur d'exécution si Pos2 est égal à Long(Ch2).
Program DETECT_ANAGRAMMES;
{Détection d'anagrammes}
(*
En entrée : {Deux chaînes de caractères }
En sortie : {'OUI' si les deux chaînes sont anagrammes l'une de l'autre'NON' dans
le cas contraire}
*)
Uses Dos, Crt;
Var Ch1, Ch2, Car : string;
Pos1, Pos2 : integer;
Anagramme, Trouve : string;
Begin
{Entrée des chaînes à analyser}
Writeln('Entrez la première chaîne :');
Readln(Ch1);
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
33
Writeln('Entrez la seconde chaîne :');
Readln(Ch2);
{Initialisation et test d'un cas particulier}
If Length(Ch1) <> Length(Ch2) Then
Anagramme:='FAUX'
Else
Anagramme:='VRAI';
{Initialisation pour la boucle externe }
Pos1:=1;
{Boucle de parcours de la première chaîne, Ch1}
While (Anagramme='VRAI') And (Pos1<=Length(Ch1)) Do Begin
{Isolement du caractère courant}
Car:=Copy(Ch1, Pos1, 1);
{Initialisations pour la boucle interne}
Pos2:=1;
Trouve:='FAUX';
{Parcours de la seconde chaîne Ch2 à la recherche du caractère Car}
While (Trouve='FAUX') and (Pos2<=Length(Ch2)) Do Begin
{Test de détection de Car dans Ch2}
If Car=Copy(Ch2, Pos2, 1) Then Begin
{Elimination du caractère dans Ch2}
Ch2:=Copy(Ch2, 1, Pos2-1)+Copy(Ch2, Pos2+1, Length(Ch2)-Pos2);
Trouve:='VRAI';
End Else
{Passage au caractère suivant dans Ch2}
Pos2:=Pos2+1;
End; {Fin du While interne}
{Passage au caractère suivant de Ch1}
If Trouve='FAUX' Then
Anagramme:='FAUX'
Else
Pos1:=Pos1+1;
End; {Fin du While externe}
{Verdict}
If Anagramme='VRAI' Then
Writeln('OUI')
Else
Writeln('NON');
End.
Figure A17.11. Détection d'anagrammes
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
34
Exercice 5
Question 1
Le programme demandé n'est pas trivial. La figure A7.12 en propose une
correction structurée. Elle est composée de quatre parties :
1. L'entrée du nombre entier à convertir. Ce nombre est mémorisé dans la
variable numérique Nb.
2. Le traitement du signe. Si le nombre est négatif le caractère '-' est mémorisé
dans la variable Signe et le nombre est multiplié par -1, dans le cas contraire la
variable Signe est mise à chaîne vide. Ainsi la partie suivante, qui s'intéresse à
la conversion proprement dite, pourra supposer que le nombre à convertir est
positif.
3. La conversion proprement dite à l'aide d'une boucle Repeat.
4. La sortie du résultat avec intégration du signe calculé à l'étape 2.
Le but de la boucle de conversion est de traduire le nombre entier positif
contenu dans la variable numérique Nb en son équivalent chaîne de caractères dans
la variable chaîne de caractères Resultat. A chaque tour de boucle un des chiffres
du nombre est traité. Chaque tour de boucle se décompose en quatre étapes :
. Isoler le chiffre le plus à droite du nombre. Le lecteur pourra se reporter au
paragraphe 6.4.4 où ce traitement a déjà été expliqué.
. Convertir le chiffre isolé en son équivalent chaîne de caractères dans la
variable Car. La conversion est réalisée à l'aide d'une grande instruction
Case...Of.
. Accumuler le chiffre converti dans la variable Resultat par l'instruction
Resultat:=Car+Resultat.
. Préparer le tour de boucle suivant en affectant à la variable Nb sa partie
gauche, c'est-à-dire lui-même mais amputé de son chiffre le plus à droite qui
vient d'être converti.
Program STR1;
{Conversion d'un nombre entier en son équivalent chaîne
de caractères}
(*
En entreé : {Un nombre entier positif ou négatif}
En sortie : {L'équivalent chaîne de caractères du nombre entré}
Remarque : Exercice technique sans effet visuel.
*)
Uses Dos, Crt;
Var Nb, Partie_Gauche, ChiffreDroit : integer;
Resultat, Car, Signe : string;
Begin
{Entrée du nombre à convertir}
Writeln('Entrez votre nombre entier :');
Readln(Nb);
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
35
{ Traitement du signe éventuel}
If Nb<0 Then Begin
Signe:='-';
Nb:=-Nb;
End Else
Signe:='';
Resultat:='';
{Boucle de 'parcours' de droite à gauche du nombre à convertir en chaîne}
Repeat
{Isolement du chiffre le plus à droite de Nb}
Partie_Gauche:=Trunc(Nb/10);
ChiffreDroit:=Nb-Partie_Gauche*10;
{Conversion en chaîne du chiffre isolé}
Case ChiffrefDroit Of
0 : Car:='0';
1 : Car:='1';
2 : Car:='2';
3 : Car:='3';
4 : Car:='4';
{On peut faire plus court en remplaçant tout le Case
Of}
5 : Car:='5';
{ par Car:=Copy('0123456789,ChiffreDroit+1,1)}
6 : Car:='6';
7 : Car:='7';
8 : Car:='8';
9 : Car:='9';
End;
{Ajout du chiffre converti au résultat}
Resultat:=Car+Resultat;
{Passage au suivant}
Nb:=Partie_Gauche;
Until Nb=0;
{Sortie du résultat pour contrôle}
Resultat:=Signe+Resultat;
Writeln(Resultat);
End.
Figure A7.12. Conversion d'un nombre entier en son équivalent chaîne de caractères
Question 2
Le programme de la figure A7.13 qui effectue le traitement demandé s'appuie
sur les trois idées suivantes :
. Couper le nombre à convertir en deux. D'un côté sa partie entière et de l'autre
sa partie décimale.
. Reprendre quasiment tel quel le programme STR1 de la figure A7.12 pour
traiter la conversion du signe et celle de la partie entière.
. Convertir séparément la partie décimale à l'aide d'une boucle appropriée.
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
36
Plus précisément ce programme est composé de 7 parties :
1. L'entrée du nombre réel à convertir. Ce nombre est mémorisé dans la variable
numérique Nb.
2. Le traitement du signe. Si le nombre est négatif le caractère '-' est mémorisé
dans la variable Signe et le nombre est multiplié par -1, dans le cas contraire la
variable Signe est mise à chaîne vide. Ainsi la partie suivante, qui s'intéresse à
la conversion proprement dite, pourra supposer que le nombre à convertir est
positif.
3. Le découpage du nombre réel à convertir. D'un côté la partie entière dans la
variable PartieEntiere et de l'autre la partie décimale dans la variable
PartieDecimale.
4. La conversion de la variable numérique PartieEntiere en son équivalent
chaîne de caractère dans la variable Resultat. Il s'agit ni plus, ni moins que de la
reprise de la troisième partie de l'algorithme STR1 de la figure A7.12. Le
lecteur pourra s'y reporter.
5. L'insertion du point décimale dans la chaîne Resultat.
6. La conversion de la variable PartieDecimale en son équivalent chaîne de
caractères. Par exemple 0.1416 donnera '1416'.
7. La sortie du résultat avec intégration du signe calculé à l'étape 2.
Hormis les problèmes de représentation des nombres décimaux en binaire
évoqués dans la remarque en fin de correction, le traitement de la sixième partie est
effectué à l'aide d'une boucle Repeat. Cette boucle converti la partie fractionnaire
contenue dans la variable PartieDecimale à la fin de la chaîne Resultat. Par
exemple si en début de boucle Résultat contient '745.' et PartieDecimale contient
0.12345 alors en fin de boucle Resultat contiendra '745.12345'. A chaque tour de
boucle un des chiffres du nombre est traité à l'aide des quatre étapes :
. Isoler le chiffre le plus à gauche de la partie décimale. Par exemple si
PartieDecimale contient 0.12345 il s'agit d'isoler le 1.
. Convertir le chiffre isolé en son équivalent chaîne de caractères dans la
variable Car. La conversion est réalisée à l'aide d'une grande instruction
Case...Of.
. Accumuler le chiffre converti dans la variable Resultat par l'instruction
Resultat:=Resultat+Car.
. Préparer le tour de boucle suivant en éliminant de la variable PartieDecimale
le chiffre qui vient d'être traduit. Ce traitement est réalisé par l'instruction
PartieDecimale:=PartieDecimale*10-ChiffreGauche.
Par
exemple
si
PartieDecimale vaut 0.12345 avant l'exécution de cette instruction, elle
contiendra 0.2345 après son exécution
Remarque : cette correction illustre bien la différence entre algorithmique et
programmation. En effet, dans la deuxième partie de ce programme, la conversion
de la partie décimale, nous avons dû faire des contorsions pour obtenir un
programme qui donne les bons résultats. En effet en Turbo PASCAL, les réels sont
codés en binaire et par voie de conséquence la partie fractionnaire des nombres
décimaux ne peut être fait que d'une manière approchée. En fait 12.7 est codé
12.6999999999997, nous avons dû utiliser une astuce (cf. programme).
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
37
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
38
Program STR2;
{Conversion d'un nombre réel en son équivalent chaîne
de caractères}
(*
En entrée : {Un nombre réel}
En sortie : {L'équivalent chaîne de caractères du nombre entré}
Remarque : Exercice technique sans effet visuel.
*)
Uses Dos, Crt;
Var NbReel, PartieDecimale, ChiffreGauche : real;
PartieEntiere, PartieGauche, ChiffreDroit : integer;
Resultat, Car, Signe : string;
Begin
{Entrée du nombre à traiter}
Writeln('Entrez votre nombre réel à convertir en chaîne :');
Readln(NbReel);
{Prise en compte du signe éventuel}
If NbReel<0 Then Begin
Signe:='-';
NbReel:=-NbReel;
End Else
Signe:='';
{Séparation de la partie entière de la partie décimale}
PartieEntiere:=Trunc(NbReel);
PartieDecimale:=NbReel-PartieEntiere;
{*** Conversion de la partie entière ***}
{'Parcours' de droite à gauche du nombre entier à convertir en chaîne}
Resultat:='';
Repeat
{Isolement du chiffre le plus à droite de PartieEntiere}
PartieGauche:=Trunc(PartieEntiere/10);
ChiffreDroit:=PartieEntiere-PartieGauche*10;
{Conversion en chaîne du chiffre isolé}
Case ChiffreDroit Of
0 : Car:='0';
1 : Car:='1';
2 : Car:='2';
3 : Car:='3';
4 : Car:='4';
{On peut faire plus court en remplaçant tout le Case
Of}
5 : Car:='5';
{ par Car:=Copy('0123456789,ChiffreDroit+1,1)}
6 : Car:='6';
7 : Car:='7';
8 : Car:='8';
9 : Car:='9';
End;
{Ajout au résultat}
Resultat:=Car+Resultat;
{Passage au suivant}
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
39
PartieEntiere:=PartieGauche;
Until PartieEntiere=0;
{*** Conversion de la partie décimale ***}
{Attention, suite à des problèmes avec la fonction trunc et de représentation}
{de nombres réels en Turbo PASCAL, nous n'avons pas pu utiliser l'instruction}
{Case...Of }
{Insertion du point décimale dans la réponse}
Resultat:=Resultat+'.';
{Boucle pour convertir la partie décimale}
Repeat
{Isolement du chiffre le plus à gauche}
{Problème de représentation décimale}
ChiffreGauche:=Int((PartieDecimale+0.000009)*10);
{Conversion en chaîne du chiffre isolé}
If ChiffreGauche=0 Then Car:='0'
Else If ChiffreGauche=1 Then Car:='1'
Else If ChiffreGauche=2 Then Car:='2'
Else If ChiffreGauche=3 Then Car:='3'
{On peut faire plus court par :}
Else If ChiffreGauche=4 Then Car:='4'
{L:='0123456789'; }
Else If ChiffreGauche=5 Then Car:='5'
{Car:=Copy(L,ChiffreGauche+1, 1)}
Else If ChiffreGauche=6 Then Car:='6'
Else If ChiffreGauche=7 Then Car:='7'
Else If ChiffreGauche=8 Then Car:='8'
Else If ChiffreGauche=9 Then Car:='9';
{Ajout au résultat}
Resultat:=Resultat+Car;
{Passage au suivant}
PartieDecimale:=PartieDecimale*10-ChiffreGauche;
Until PartieDecimale<=0.000009;
{Pb de représentation des réels}
{Sortie du résultat}
Resultat:=Signe+Resultat;
Writeln(Resultat);
End.
Figure A7.13. Conversion d'un nombre réel en son équivalent chaîne de caractères
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
40
FEUILLE D'EXERCICES NUMÉRO 3
Exercice 1
Le programme de la figure A7.14 réalise le traitement demandé. Il est composé
d'une boucle For dont le compteur I est initialisé à 0 et est incrémenté de 1 à
chaque tour de boucle jusqu'à atteindre la valeur 99 (incluse). Pour chaque valeur
de I, la valeur I*2 est sortie.
A titre d'exercice supplémentaire, le lecteur est invité à réécrire ce programme
en remplaçant l'instruction For par une instruction While ou Repeat.
Program NOMBRES_PAIRS;
{Affichage des cent premiers nombres
pairs}
{
En entrée : rien
En sortie : {Les cent premiers nombres pairs : 0, 2, 4, ..., 198 }
Uses Dos, Crt;
Var i : integer;
Begin
For i:=0 to 99 Do
Writeln(I*2:3);
End.
Figure A7.14. Affichage des cent premiers nombres pairs
Exercice 2
Le programme de la figure A7.15 réalise le traitement demandé. Il est composé
de quatre parties :
1. L'entrée de la chaîne à traiter. Celle pour laquelle il faut compter le nombre
de lettres majuscules. La chaîne entrée est mémorisée dans la variable Ch.
2. L'initialisation de la variable TotalMajuscule. Cette variable va être notre
compteur de lettres majuscules.
3. Le parcours, caractère par caractère, de la chaîne entrée à l'aide d'une boucle
For.
4. La sortie du résultat du comptage, c'est-à-dire le contenu de la variable
TotalMajuscule.
TotalMajuscule va contenir le nombre de lettres majuscules rencontrés. En
début d'exécution, aucun caractère n'ayant été traité, il est logique d'initialiser
TotalMajuscules à zéro.
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
41
Le parcours, caractère par caractère, de la chaîne Ch est programmé avec une
boucle For. La variable de parcours est la variable Pos qui varie de 1 à Long(Ch).
Pour chaque valeur de Pos, le Posème caractère de la chaîne Ch est isolé dans la
variable Car grâce à l'instruction Car:=SChain(Ch, Pos, 1). Ensuite, le test
(Car>='A') and (Car<='Z') permet de détecter la présence d'une lettre majuscule
et, le cas échéant, de mettre à jour la variable TotalMajuscule.
A titre d'exercice supplémentaire, le lecteur est invité à réécrire ce programme
en utilisant l'instruction Repeat ou While au lieu de l'instruction For.
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
42
Program COMPTE_MAJUSCULE;
{Comptage du nombre de lettres
majuscules d'une chaîne de caractères}
Uses Dos, Crt;
Var Ch, Car : string;
Pos, TotalMajuscule : integer;
Begin
{Entrée de la chaîne à traiter}
Writeln('Entrez votre chaîne de caractères :');
Readln(Ch);
{Initialisation du compteur de lettres majuscules}
TotalMajuscule:=0;
{Boucle de parcours de la chaîne avec comptage du nombre de majuscules}
For Pos:=1 to length(Ch) do Begin
{Isolement du caractère courant}
Car:=copy(Ch,Pos,1);
{Test si le caractère courant est une lettre majuscule}
If (Car>='A') and (Car<='Z') Then
TotalMajuscule:=TotalMajuscule+1;
End;
{Affichage du résultat}
Writeln(TotalMajuscule:3);
End.
Figure A7.15. Comptage du nombre de lettres majuscules d'une chaîne de caractères
Exercice 3
Le programme de la figure A7.16 réalise le traitement demandé. Il est composé
de quatre parties :
1. L'entrée de la chaîne à traiter. Celle pour laquelle il faut remplacer chaque
voyelle par le caractère '*'. Cette chaîne est mémorisée dans la variable Ch.
2. L'initialisation de la variable Resultat avec la chaîne vide. Cette variable va
contenir la chaîne traduite, c'est-à-dire la chaîne initiale mais dans laquelle on
aura remplacée chaque voyelle par le caractère '*'.
3. Le parcours, caractère par caractère, de la chaîne entrée à l'aide d'une boucle
For. Au fur et à mesure de l'avancement dans le parcours de la chaîne Ch, cette
boucle va construire la chaîne souhaitée dans la variable Resultat.
4. La sortie du résultat, c'est-à-dire le contenu de la variable Resultat.
Le parcours, caractère par caractère, de la chaîne Ch est programmé avec une
boucle For. La variable de parcours est la variable Pos qui varie de 1 à Long(Ch).
Pour chaque valeur de Pos, le Posème caractère de la chaîne Ch est isolé dans la
variable Car grâce à l'instruction Car:=SChain(Ch, Pos, 1). Ensuite, grâce à une
longue condition (cf. programme), si Car est une voyelle il est remplacé par le
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
43
caractère '*'. Et finalement Car est ajouté à la chaîne Resultat par l'instruction
Resultat:=Resultat+Car.
A titre d'exercice supplémentaire, le lecteur est invité à réécrire ce programme
en utilisant l'instruction Repeat ou While au lieu de l'instruction For.
Program REMPLACE_ETOILE;
{Remplacement des voyelles d'une
chaîne de caractères par le caractère étoile}
(*
En entrée : une chaîne de caractères quelconque
En sortie : la même chaîne de caractères mais où l'on aura remplacé chaque voyelle
par une *
*)
Uses Dos, Crt;
Var Ch, Resultat, Car : string;
Pos : integer;
Begin
{Entrée de la chaîne à traiter}
Writeln('Entrez votre chaîne de caractères :');
Readln(Ch);
{Initialisation}
Resultat:='';
{Boucle de parcours de la chaîne et remplacement des voyelles}
For Pos:=1 to Length(Ch) do Begin
{Isolement du caractère courant}
Car:=copy(Ch, Pos, 1);
{Test si le caractère courant est une voyelle}
If (Car='A') or (Car='E') or (Car='I') or (Car='O') or (Car='U') or (Car='Y')
or (Car='a') or (Car='e') or (Car='i') or (Car='o') or (Car='u') or (Car='y')
Then Car:='*';
{Ajout du caractère courant, éventuellement modifié, à Resultat}
Resultat:=Resultat+Car;
End; {Fin du For}
{Sortie du résultat}
Writeln(Resultat);
End.
Figure A7.16. Remplacement des voyelles d'une chaîne de caractères par le caractères '*'
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
44
Exercice 4
Program SOMME_PAR_3;
{Exercice sur les boucles imbriquées}
(*
En entrée : douze nombres
En sortie : leurs sommes trois par trois
*)
Uses Dos, Crt;
Var Nb, I, J, Somme : integer;
Begin
{Boucle externe qui fait varier I de 1 à 4}
For i:=1 to 4 Do Begin
{Réinitialisation de la variable de mémorisation des sommes
intermédiaires}
Somme:=0;
{Boucle interne qui pour chaque I, fait varier J de 1 à 3}
For j:=1 to 3 Do Begin
{Entrée du nombre suivant}
Writeln('Entrez votre nombre numéro ',(i-1)*3+j:2,' :');
Readln(Nb);
{Prise en compte du nombre entré dans la somme intermédiaire}
Somme:=Somme+Nb;
End;
{Sortie de la somme des trois derniers nombres entrés}
Writeln(Somme:5);
End;
End.
Figure A7.17. Exercice sur les boucles imbriquées
Exercice 5
Question 1
Program VAL1;
{Conversion d'une chaîne de caractères en un nombre
entier}
(*
En entrée : {Une chaîne de caractères quelconque}
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
45
En sortie : {Son équivalent numérique (entier) ou "ERREUR" }
Remarque : Exercice technique sans effet visuel.
*)
Uses Dos, Crt;
Var Ch, Signe, Car, Erreur : string;
Nb, NbCar, Pos : integer;
Begin
{Entrée de la chaîne à traiter}
Writeln('Entrez votre chaîne :');
Readln(Ch);
{Prise en compte du cas de la chaîne vide}
If Ch='' Then
Erreur:='VRAI'
Else Begin
{Initialisations}
Erreur:='FAUX';
Nb:=0;
{Traitement du signe éventuel}
If (copy(Ch, 1, 1)='+') or (copy(Ch, 1, 1)='-') Then Begin
Signe:=copy(Ch, 1, 1);
Ch:=Copy(Ch, 2, Length(Ch)-1);
End Else
Signe:='+';
{Parcours de la chaîne à convertir}
Pos:=1;
While (Erreur='FAUX') and (Pos<=Length(Ch)) Do Begin
{Isolment du caractère courant}
Car:=Copy(Ch, Pos, 1);
{Conversion du caractère courant}
If Car='0' Then NbCar:=0
Else If Car='1' Then NbCar:=1
Else If Car='2' Then NbCar:=2
Else If Car='3' Then NbCar:=3
Else If Car='4' Then NbCar:=4
Else If Car='5' Then NbCar:=5
Else If Car='6' Then NbCar:=6
Else If Car='7' Then NbCar:=7
Else If Car='8' Then NbCar:=8
Else If Car='9' Then NbCar:=9
Else Erreur:='VRAI';
If Erreur='FAUX' Then
{Prise en compte du résultat du dernier chiffre converti}
Nb:=Nb*10+NbCar;
{Passage à la position suivante de Ch}
Pos:=Pos+1;
End; {Fin du While}
{Prise en compte du signe}
If Signe='-' Then
Nb:=-Nb;
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
46
End; {Fin du If}
{Verdict}
If Erreur='VRAI' Then
Writeln('ERREUR')
Else
Writeln(Nb:5);
End.
Figure A7.18. Conversion d'une chaîne de caractères en un nombre entier
Question 2
Program VAL2;
{Conversion d'une chaîne de caractères en un nombre
réel}
(*
En entrée : {Une chaîne de caractères}
En sortie : {Son équivalent numérique (réel) ou "ERREUR" }
Remarque : Exercice technique sans effet visuel.
*)
Uses Dos, Crt;
Var Ch, Signe, Car : string;
Fini, Erreur : string;
Nb, NbCar, P10 : real;
Pos : integer;
Begin
{Entrée de la chaîne à traiter}
Writeln('Entrez votre chaîne :');
Readln(Ch);
{Traitement du cas de la chaîne vide}
If Ch='' Then
Erreur:='VRAI'
Else Begin
{Initialisations}
Erreur:='FAUX';
Nb:=0;
{Traitement du signe éventuel}
If (copy(Ch, 1, 1)='+') or (copy(Ch, 1, 1)='-') Then Begin
Signe:=copy(Ch, 1, 1);
Ch:=Copy(Ch, 2, Length(Ch)-1);
End Else
Signe:='+';
{*** Parcours de la chaîne pour convertir la PARTIE ENTIERE ***}
Pos:=1;
Fini:='FAUX';
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
47
While (Erreur='FAUX') and (Fini='FAUX') Do Begin
{Test si le parcours de la chaîne est finie}
If Pos>Length(Ch) Then
Fini:='VRAI'
{Test si le parcours de la partie entière est finie}
Else If copy(Ch, Pos, 1)='.' Then
Fini:='VRAI'
Else Begin
{Isolement du caractère courant}
Car:=Copy(Ch, Pos, 1);
{Conversion du caractère courant en son équivalent chiffre}
If Car='0' Then NbCar:=0
Else If Car='1' Then NbCar:=1
Else If Car='2' Then NbCar:=2
Else If Car='3' Then NbCar:=3
Else If Car='4' Then NbCar:=4
Else If Car='5' Then NbCar:=5
Else If Car='6' Then NbCar:=6
Else If Car='7' Then NbCar:=7
Else If Car='8' Then NbCar:=8
Else If Car='9' Then NbCar:=9
Else If Car='.' Then Fini:='VRAI'
Else Erreur:='VRAI';
If Erreur='FAUX' Then
{Prise en compte du résultat du dernier chiffre converti}
Nb:=Nb*10+NbCar;
{Passage à la position suivante de Ch}
Pos:=Pos+1;
End; {Fin de la partie Else}
End; {Fin du While}
{**Parcours de la fin de la chaîne pour convertir la partie DECIMALE**}
If Erreur='FAUX' Then Begin
If Pos<=Length(Ch) Then Begin
{Passage de l'éventuel point ('.') décimal}
If Copy(Ch, Pos, 1)='.' Then Begin
{Passage à la position suivante de Ch}
Pos:=Pos+1;
P10:=10; (* pour générer les puissances de 10 : 10, 100, 1000, ... *)
{Boucle de conversion de la partie décimale}
While (Pos<=Length(Ch)) and (Erreur='FAUX') Do Begin
{Isolement du caractère courant}
Car:=Copy(Ch, Pos, 1);
{Conversion en chiffre du dernier caractère isolé}
If Car='0' Then NbCar:=0
Else If Car='1' Then NbCar:=1
Else If Car='2' Then NbCar:=2
Else If Car='3' Then NbCar:=3
Else If Car='4' Then NbCar:=4
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
48
Else If Car='5' Then NbCar:=5
Else If Car='6' Then NbCar:=6
Else If Car='7' Then NbCar:=7
Else If Car='8' Then NbCar:=8
Else If Car='9' Then NbCar:=9
Else Erreur:='VRAI';
If Erreur='FAUX' Then Begin
{Prise en compte du résultat du dernier chiffre converti}
Nb:=Nb+(NbCar/P10);
P10:=P10*10;
End;
{Passage à la position suivante de Ch}
Pos:=Pos+1;
End; {Fin du While}
End; {Fin du If Copy(Ch, Pos, 1)='.'}
End; {Fin du If Pos<=Length(Ch)}
End; {Fin du If Erreur='FAUX'}
End; {Fin du If Ch=''}
{Prise en compte du signe}
If (Erreur='FAUX') and (Signe='-') Then
Nb:=-Nb;
{Verdict}
If Erreur='VRAI' Then
Writeln('ERREUR')
Else
Writeln(Nb:8:4);
End.
Figure A7.19. Conversion d'une chaîne de caractères en un nombre réel
Exercice 6
Cette première correction considère qu'une chaîne de caractères est une suite de
séquences de blancs et de mots L'algorithme est donc constitué d'une grande boucle
qui permet de parcourir l'entièreté de la chaîne entrée. Cette grande boucle contient
deux boucles en série : la première pour 'manger' les blancs et une deuxième pour
isoler les mots.
Program MOT1;
{Liste des mots d'une chaîne de caractères. Version 1}
(*
En entrée : une chaîne de caractères quelconque
En sortie : la liste des mots composant cette chaîne
*)
Uses Dos, Crt;
Var Ch, Mot, Car : string;
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
49
Fini, Trouve : string;
Pos : integer;
Begin
{Entrée de la chaîne à traiter }
Writeln('Entrez votre chaîne de caractères :');
Readln(Ch);
{Initialisations en vue du parcours de la chaîne entrée}
Pos:=1;
Fini:='FAUX';
{Boucle de parcours de la chaîne de caractères entrée}
While Fini='FAUX' Do Begin
{Boucle de parcours de la chaîne tant que l'on rencontre des BLANCS}
Trouve:='FAUX';
While (Fini='FAUX') and (Trouve='FAUX') Do Begin
{A-t-on fini atteint la fin de la chaîne}
If Pos>Length(Ch) Then
Fini:='VRAI'
Else Begin
{Isolement du caractère courant}
Car:=Copy(Ch, Pos, 1);
{A-t-on rencontré le début d'un mot, i.e. un caractère <> de blanc}
If Car<>' ' Then (* Car est différent de blanc *)
Trouve:='VRAI'
Else
{Passage à la position suivante dans Ch}
Pos:=Pos+1;
End;
End; {Fin du While}
{Parcours de la chaîne tant que l'on reste dans un MOT, i.e. tant que
{l'on rencontre des caractères différent du blanc}
Mot:='';
Trouve:='FAUX';
While (Fini='FAUX') and (Trouve='FAUX') Do Begin
{A-t-on atteint la fin de la chaîne}
If Pos>Length(Ch) Then
Fini:='VRAI'
Else Begin
{Isolement du caractère courant}
Car:=Copy(Ch, Pos, 1);
{A-t-on rencontré la fin du mot, i.e. un caractère blanc}
If Car=' ' Then (* Car est égal à blanc *)
Trouve:='VRAI'
Else Begin (* donc <> ' ' *)
{Formation du mot}
Mot:=Mot+Car;
{Passage à la position suivante de Ch}
Pos:=Pos+1;
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
50
End;
End;
End; {Fin du While}
{Sortie du mot isolé }
If Mot<>'' Then
Writeln(Mot);
End; {Fin du While externe}
End.
Figure A7.20. Liste des mots d'une chaîne de caractères. Version 1
Cette deuxième correction considère qu'une chaîne de caractères est avant tout
une suite de caractères et l'algorithme est donc constitué d'une seule boucle qui
permet de la parcourir caractère par caractère. A l'intérieur de la boucle, la variable
Mot a un double rôle. D'abord celui de 'recueillir' les mots rencontrés, et, ensuite
celui de permettre de savoir où l'on en était lors du précédent tour de boucle : soit
déjà dans un mot : le contenu de la variable Mot est alors différent de chaîne vide;
soit hors d'un mot : son contenu est alors égal à chaîne vide.
Program MOT2; {Liste des mots d'une chaîne de caractères. Version 2}
(*
En entrée : {Une chaîne de caractères quelconque}
En sortie : {La liste des mots composant cette chaîne}
Remarque : cet algorithme est composé d'une seule boucle
*)
Uses Dos, Crt;
Var Ch, Mot, Car : string;
Pos : integer;
Begin
{Entrée de la chaîne à traiter}
Writeln('Entrez votre chaîne de caractères :');
Readln(Ch);
{Initialisation en vue de la boucle de parcours de la chaîne à traiter}
Mot:='';
{Boucle de parcours de la chaîne de caractères}
For Pos:=1 to Length(Ch) Do Begin
{Isolement du caractère courant}
Car:=Copy(Ch, Pos, 1);
{On est en présence d'un caractère <> de blanc, donc dans un mot}
If Car<>' ' Then
{"J'accumule" les lettres formant le mot}
Mot:=Mot+Car
Else Begin {donc Car=' '}
If Mot<>'' Then Begin {Mot différent de chaîne vide}
{Sortie du dernier mot isolé}
Writeln(Mot);
{Réinitialisation de 'l'accumulateur' de lettres}
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
51
Mot:='';
End;
End;
{Passage à la position suivante de Ch}
End; {Fin du For}
{Le dernier mot, s'il n'est pas suivi d'un blanc, est resté dans le buffer}
If Mot<>'' Then
Writeln(Mot);
End.
Figure A7.21. Liste des mots d'une chaîne de caractères. Version 2
FEUILLE D'EXERCICES NUMÉRO 4
Exercice 1
Program FACTORIEL;
{Calcul de factoriel N}
Uses Dos, Crt;
Var N, I : integer;
Produit : real; {Le type integer ne peut contenir de nombre >32767}
Begin
{Entrée du nombre pour lequel il faut calculer la factorielle}
Writeln('Entrez votre nombre : ');
Readln(N);
{Boucle de calcul de factoriel}
Produit:=1;
For i:=1 to N Do
Produit:=Produit*i;
{Sortie du résultat}
Writeln(Produit:8:0);
End.
Figure A7.22. Calcul de factoriel N
Exercice 2
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
52
Program POURCENTAGE;
{Calcul du pourcentage de voyelles et de
consonnes}
(*
En entrée : {Une chaîne de caractères quelconque}
En sortie : {Le pourcentage de voyelles et de consonnes de la chaîne entrée}
*)
Uses Dos, Crt;
Var Ch, Car : string;
Pos, TotalVoyelles, TotalConsonnes : integer;
PourCentVoyelles, PourCentConsonnes: real;
Begin
{Entrée de la chaîne à traitée}
WriteLn('Entrez votre chaîne de caractères :');
Readln(Ch);
{Boucle de comptage du nombre de voyelles et de consonnes}
TotalVoyelles:=0;
TotalConsonnes:=0;
Pos:=1;
While Pos<=Length(Ch) do begin
Car:=copy(Ch, Pos, 1);
{Test si on est en présence d'un lettre}
If ( (Car>='A') and (Car<='Z') ) Or ( (Car>='a') and (Car<='z') ) Then
{Test si on est en présence d'une voyelle}
if (Car='A') or (Car='E') or (Car='I') or (Car='O') or (Car='U') or (Car='Y')
or (Car='a') or (Car='e') or (Car='i') or (Car='o') or (Car='u') or (Car='y')
Then
TotalVoyelles:=TotalVoyelles+1
Else
TotalConsonnes:=TotalConsonnes+1;
{Passage à la position suivante deCh}
Pos:=Pos+1;
End;
{Calcul final et sortie des résultats}
PourCentVoyelles:=TotalVoyelles/Length(Ch)*100;
PourCentConsonnes:=TotalConsonnes/Length(Ch)*100;
WriteLn('Le pourcentage de voyelles est :', PourCentVoyelles:6:4);
WriteLn('Le pourcentage de consonnes est :', PourCentConsonnes:6:4);
End.
Figure A7.23. Calcul du pourcentage de voyelles et de consonnes
Exercice 3
Cette première correction construit la chaîne inverse de la chaîne entrée, ainsi
'BONBON' devient 'NOBNOB', puis teste cette chaîne inverse avec la chaîne
entrée. Si les deux chaînes sont identiques alors c'est un palindrome sinon ce n'est
pas un palindrome. Ce programme n'est pas très efficace en temps calcul, car il y a
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
53
un premier parcours de la chaîne entrée pour construire la chaîne inverse et ensuite
le test de la chaîne entrée avec la chaîne inverse oblige le système, en interne, à
parcourir encore une fois la chaîne entrée pour détecter l'égalité.
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
54
Program PALINDROME1;
{Détection de palindrome. Version 1}
(*
En entrée : {Une chaîne de caractères quelconque}
En sortie : {La chaîne 'OUI' si la chaîne entrée est un palindrome et la chaîne
'NON' dans le cas contraire}
*)
Uses Dos, Crt;
Var Ch, Envers : string;
Pos : integer;
Begin
{Entrée de la chaîne à traiter}
Writeln('Entrez votre chaîne :');
Readln(Ch);
{Construction de la chaîne inverse}
Envers:='';
For Pos:=1 to Length(Ch) Do Begin
Envers:=copy(Ch, Pos, 1)+Envers;
End;
{Verdict}
If Ch=Envers Then
Writeln('OUI')
Else
Writeln('NON');
End.
Figure A7.24. Détection de palindrome. Version 1
Cette deuxième correction test caractère par caractère la première moitié de la
chaîne entrée avec sa seconde moitié : le premier caractère est testé avec le dernier,
le deuxième caractère avec l'avant-dernier, le troisième caractère avec
l'antépénultième, ... jusqu'au milieu de la chaîne. Si tous les tests sont positifs,
égalité des caractères, alors c'est un palindrome.
Program PALINDROME2;
{Détection de palindrome. Version 2}
(*
En entrée : {Une chaîne de caractères quelconque}
En sortie : {La chaîne 'OUI' si la chaîne entrée est un palindrome et la chaîne
'NON' dans le cas contraire}
*)
Uses Dos, Crt;
Var Ch, Car1, Car2, Palindrome : string;
Pos, PosMilieu : integer;
Begin
{Entrée de la chaîne à traiter}
Writeln('Entrez votre chaîne :');
Readln(Ch);
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
55
{Initialisations}
PosMilieu:=trunc(Length(Ch)/2);
Pos:=1;
Palindrome:='VRAI';
{Test de la première moitié de la chaîne saisie avec sa deuxième moitié}
While (Pos<=PosMilieu) and (Palindrome='VRAI') Do Begin
{Isolement du caractère de la première moitie de la chaîne}
Car1:=Copy(Ch, Pos, 1);
{Isolement du caractère de la deuxième moitié de la chaîne}
Car2:=Copy(Ch, Length(Ch)-Pos+1,1);
{Test d'égalité des deux caractères isolés}
If Car1<>Car2 Then
Palindrome:='FAUX'
Else
Pos:=Pos+1;
End;
{Verdict}
If Palindrome='VRAI' Then
WriteLn('OUI')
Else
Writeln('NON');
End.
Figure A7.25. Détection de palindrome. Version 2
Une autre solution, fort élégante, consiste à utiliser deux variables : Début et
Fin. La variable Début est initialisé à 1 et la variable Fin à Length(Ch). A chaque
tour de boucle, on compare Copy(Ch, Debut,1) avec Copy(Ch, Fin, 1). Si le test est
Faux alors ce n'est pas un palindrome et s'il est Vrai alors on incrémente Debut de
+1 et on décrément Fin de -1. La boucle s'arrête dès que Debut>Fin ou bien
entendu s'il un des tests de comparaison a été évalué à Faux.
Exercice 4
Program PUISSANCE_10;
{Calcul de la plus petite puissance de 10 plus
grande qu'un nombre donné}
(*
En entrée {Unombre entier positif}
En sortie : {La plus petite puissance de 10 plus grande que le nombre entré}
*)
Uses Dos, Crt;
Var Nb, P10 : integer;
Begin
{Entrée des données}
Writeln('Entrez un nombre entier :');
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
56
Readln(Nb);
{Initialisation : dix puissance zéro est égal à 1}
P10:=1;
{Boucle de calcul-détection}
While P10<Nb Do
{Génération de la puissance de 10 suivante}
P10:=P10*10;
{Vedict}
Writeln(P10:5);
End.
Figure A7.26. Calcul de la plus petite puissance de 10 plus grande qu'un nombre donné
Exercice 5
Question 1
Program PERSISTANCE1;
{Question 1 sur le calcul de la persitance d'un
nombre}
(*
En entrée : {Un nombre entier quelconque}
En sortie : {La liste de droite à gauche des chiffres qui compose le nombre entré}
*)
Uses Dos, Crt;
Var Nb, PartieGauche, ChiffreDroit : integer;
Begin
{Entrée du nombre à décomposer}
Writeln('Entrez votre nombre :');
Readln(Nb);
{Boucle réalisant la décomposition}
Repeat
{Isolement de la partie gauche de Nb}
PartieGauche:=Trunc(Nb/10);
{Isolement du chiffre de droite de Nb}
ChiffreDroit:=Nb-PartieGauche*10;
Writeln(ChiffreDroit);
{Préparation du tour de boucle suivant}
Nb:=PartieGauche;
Until Nb=0;
End.
Figure A7.27. Question 1 sur le calcul de la persistance d'un nombre
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
57
Question 2
Program PERSISTANCE2;
{Question 2 sur le calcul de la persitance d'un
nombre}
(*
En entrée : {Un nombre entier quelconque}
En sortie : {Le produit des chiffres qui compose le nombre entré}
*)
Uses Dos, Crt;
Var Nb, PartieGauche, ChiffreDroit, Produit : integer;
Begin
{Entrée du nombre pour lequel il faut calculer le produit de ses chiffres}
Writeln('Entrez votre nombre :');
Readln(Nb);
{Initialisation}
Produit:=1;
{Boucle calculant le produit}
Repeat
{Isolement de la partie gauche de Nb}
PartieGauche:=Trunc(Nb/10);
{Isolement du chiffre de droite de Nb}
ChiffreDroit:=Nb-PartieGauche*10;
{Intégration dans le résultat final du chiffre droit isolé}
Produit:=Produit*ChiffreDroit;
{Préparation du tour de boucle suivant}
Nb:=PartieGauche;
Until Nb=0;
{Sortie du résultat}
Writeln(Produit:3);
End.
Figure A7.28. Question 2 sur le calcul de la persistance d'un nombre
Question 3
Program PERSISTANCE3;
{Calcul de la persitance d'un nombre}
(*
En entrée : {Un nombre entier quelconque}
En sortie : {La persistance de ce nombre}
*)
Uses Dos, Crt;
Var Nb, PartieGauche, ChiffreDroit : integer;
Produit, Persistance : integer;
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
58
Begin
{Entrée du nombre pour lequel il faut calculer la persistance}
Writeln('Entrez votre nombre :');
Readln(Nb);
{Initialisation du compteur de la persistance}
Persistance:=0;
{Boucle externe de progression de la persistance}
While Nb>=10 Do Begin
{Initialisations de la boucle interne}
Produit:=1;
{Boucle interne calculant le produit des chiffres composant Nb}
Repeat
{Isolement de la partie gauche de Nb}
PartieGauche:=Trunc(Nb/10);
{Isolement du chiffre de droite de Nb}
ChiffreDroit:=Nb-PartieGauche*10;
{Intégration dans le résultat final du chiffre droit isolé}
Produit:=Produit*ChiffreDroit;
{Préparation du tour suivant de la boucle interne}
Nb:=PartieGauche;
Until Nb=0;
{Prise en compte de l'augmentation de +1 de la persistance}
Persistance:=Persistance+1;
{Préparation pour le tour suivant de la boucle externe}
Nb:=Produit;
End; {Fin du While}
{Sortie du résultat}
Writeln(Persistance:3);
End.
Figure A7.29. Calcul de la persistance d'un nombre
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
59
Annexe 8
Correction des exercices du chapitre 7
A8.1. CORRECTION DES EXERCICES
Exercice 1
Program SOUS_PROGRAMME1;
{Programmation et appel du sousprogramme HEUR_SEC de conversion d'une heure en son équivalent
seconde}
Uses Dos, Crt;
Var Heure, Seconde : real;
Procedure HEUR_SEC(HH:real;Var SS : real);
(*
En entrée : {Un nombre dans HH censé représenter uen heure sous la forme
HHMMSS}
En sortie : {L'équivalent en seconde de l'heure de HH}
*)
Var Heure, Minute, Seconde, Travail : real;
Begin
{Isolement des heures}
Heure:=int(HH/10000);
Travail:=HH-Heure*10000;
{Isolement des minutes}
Minute:=Int(Travail/100);
{Isolement des secondes}
Seconde:=Travail-Minute*100;
{Conversion en seconde}
SS:=Heure*3600+Minute*60+Seconde;
End;
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
60
{DEBUT DU PROGRAMME PRINCIPAL}
Begin
{Entrée d'une donnée de test}
Writeln('Entrez une heure (102000 = 10h20mn0sec.) :');
Readln(Heure);
{Appel du sous-programme}
Heur_Sec(Heure,Seconde);
{Sortie du résultat pour contrôle}
Writeln('Total de secondes :',Seconde:8:0);
End.
Figure A8.1. Programmation et appel du sous-programme Heur_Sec
Exercice 2
Program SOUS_PROGRAMME2;
{Programmation et appel du sousprogramme Delete de suppression d'une sous-chaîne}
Uses Dos, Crt;
Var Ch : string;
Pos, Longueur : integer;
Procedure DELETE(Var Ch: string; Pos, Num : integer);
(*
En entrée : {Une chaîne quelconque dans CH}
En sortie : {Ch amputée de sa sous-chaîne commençant à la position Pos sur une
longueur de Num}
*)
Begin
{Cas de paramètres hors-limites}
If (Pos<1) or (Pos>Length(Ch)) Then
{Rien à faire : Ch est inchangée}
Else
If Pos+Num>Length(Ch) Then
{Suppression de la fin de chaîne}
Ch:=Copy(Ch, 1, Pos-1)
Else
{Suppression du milieu de chaîne}
Ch:=Copy(Ch, 1, Pos-1)+Copy(Ch, Pos+Num, Length(Ch)-Pos-Num+1);
End;
{DEBUT DU PROGRAMME PRINCIPAL}
Begin
{Entrée des données de test}
Writeln('Entrez la chaîne à traiter :');
Readln(Ch);
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
61
Writeln('Entrez la position de début de suppression :');
Readln(Pos);
Writeln('Entrez la longueur de suppression :');
Readln(Longueur);
{Appel du sous-programme}
Delete(Ch, Pos, Longueur);
{Sortie du résultat pour contrôle}
Writeln('On obtient : ',Ch);
End.
Figure A8.2. Programmation et appel du sous-programme Delete
Exercice 3
Program SOUS_PROGRAMME3;
{Programmation et appel du sousprogramme Insert d'insertion d'une chaîne dans une autre}
Uses Dos, Crt;
Var
Fleche, Cible : string;
Pos : integer;
Procedure INSERT(Fleche : string; Var Cible : string; Pos : integer);
(*
En entrée : {Une chaîne de caractères quelconque dans Cible}
En sortie : { Flèche a été insérée dans la chaîne Cible, après la position Pos}
*)
Begin
{Cas des paramètres hors-limites}
if (Pos<0) or (Pos>length(Cible)) Then
{Rien à faire : Ch reste inchangée}
Else
If Pos=Length(Cible) Then
{Insertion en fin de Cible}
Cible:=Cible+Fleche
Else
{Insertion en milieu de Cible}
Cible:= Copy(Cible, 1, Pos)+Fleche+copy(Cible, Pos+1, length(Cible)Pos);
End;
{DEBUT DU PROGRAMME PRINCIPAL}
Begin
{Entrée des données de tests}
Writeln('Entrez la chaîne à insérer :');
Readln(Fleche);
Writeln('Entrez la chaîne cible de l''insertion :');
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
62
Readln(Cible);
Writeln('Entrez la position de l''insertion :');
Readln(Pos);
{Appel du sous-programme}
Insert(Fleche, Cible, Pos);
{Sortie du résultat pour contrôle}
Writeln('On obtient : ', Cible);
End.
Figure A8.3. Programmation et appel du sous-programme Insert
Exercice 4
Program SOUS_PROGRAMME4;
fonction Compte}
Uses Dos, Crt;
Var Ch : string;
{Programmation et appel de la
Function COMPTE(Ch : string):integer;
(*
En entrée : {Une chaîne quelconque dans Ch}
En sortie : {Compte renvoie le nombre de caractères numériques présents dans
Ch}
Var I, TotalNum : integer;
Car : string;
Begin
{Initialisation}
TotalNum:=0;
{Boucle de parcours de la chaîne et comptage de ses caractères numériques}
For i:=1 to length(Ch) Do Begin
{Isolement du caractère courant}
Car:=copy(Ch, i, 1);
{Test si Car est un caractère numérique}
If (Car>='0') and (Car<='9') Then
{Mise à jour du compteur de caractères numériques}
TotalNum:=TotalNum+1;
End;
{Renvoi du résultat à la fonction}
Compte:=TotalNum;
End;
{DEBUT DU PROGRAMME PRINCIPAL}
Begin
{Entrée des données de tests}
WriteLn('Entrez la chaîne à traiter :');
Readln(Ch);
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
63
{Appel de la fonction avec sortie du résultat pour contrôle}
Writeln('Nombre de caractères numériques : ',Compte(Ch):3);
End.
Figure A8.4. Programmation et appel de la fonction Compte
A8.2. CORRECTION DU PROBLEME
Question 1
a) On peut obtenir la chaîne PASCAL\CALCUL.PAS grâce à la suite de
réécriture suivante :
On part de l'axiome
Chemin_Dos
Par la règle 1, on obtient
Nom_Dir \ Nom_Fic
Par la règle 3, on obtient
Nom_Fic \ Nom_Fic
Par la règle 4, on obtient
Car_permis Car_permis Car_permis Car_permis Car_permis Car_permi
s \ Nom_Fic
Par la règle 5 appliquée 6 fois, on obtient
PASCAL \ Nom_Fic
Par la règle 4, on obtient
PASCAL \ Car_permis Car_permis Car_permis Car_permis Car_permis
Car_permis . Car_permis Car_permis
Par la règle 5, appliquée 9 fois, on obtient finalement :
PASCAL \ CALCUL.PAS
a) On peut obtenir la chaîne C:..\..\UTIL.DIR\CHAPITRE.1 grâce à la suite de
réécriture suivante :
On part de l'axiome
Chemin_Dos
Par la règle 1, on obtient
Lecteur Nom_Dir \ Nom_Dir \Nom_Dir \ Nom_Fic
Par la règle 2, on obtient
C: Nom_Dir \ Nom_Dir \Nom_Dir \ Nom_Fic
Par la règle 3, on obtient
C: .. \ Nom_Dir \Nom_Dir \ Nom_Fic
Par la règle 3, on obtient
C: .. \ .. \Nom_Dir \ Nom_Fic
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
64
Par la règle 3, on obtient
C: .. \ .. \Nom_Ficr \ Nom_Fic
Par la règle 4, on obtient
C: .. \ .. \ Car_permis Car_permis Car_permis Car_permis .Carpermis Car_p
ermis . Car_permis Car_permis \ Nom_Fic
Par la règle 5, appliquée 7 fois, on obtient finalement :
C: .. \ .. \ UTIL.DIR \ Nom_Fic
Par la règle 4, on obtient
C: .. \ .. \ UTIL.DIR \ Car_permis Car_permis Car_permis Car_permis .Car_
permis Car_permis Car_permis Car_permis \ Car_Permis
Par la règle 5, appliquée 9 fois, on obtient finalement :
C:..\..\UTIL.DIR\CHAPITRE.1
Question 2
Procedure LECTEUR(Ch: string;Var Pos:integer; Var Bon:boolean);
{Détection d'indication de lecteur : A:, B: ou C:}
(*
Cette procédure teste si à la position Pos de Ch on trouve l'indication d'un lecteur : A:,
B: ou C:.
Si OUI alors
Bon est mis à vrai
Pos est avancée d'autant que l'analyse en a eu besoin. Donc ici +2
Sinon
Bon est mis à false et
Pos est resté inchangée
*)
Var Car : string; {Variable de travail}
Begin
{Cas où Pos est trop près de la fin de la chaîne}
If Pos+2>=length(CH) Then
Bon:=False
Else Begin
{Isolement du premier caractère}
Car:=Upcase(Ch[Pos]); {Mise en majuscule du caractère numéro Pos}
{Test de la présence d'une indication de lecteur : A:, B: ou C:}
If ((Car='A') or (Car='B') or (Car='C')) and (copy(Ch, Pos+1,1)=':') Then
Begin
Bon:=True;
Pos:=Pos+2;
End else
Bon:=False
End;
End;
Figure A8.5. Détection d'indication de lecteur : A:, B: ou C:
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
65
Question 3
Procedure SLASH(Ch: string; Var Pos: integer; Var Bon:Boolean);
{Détection d'indication de chemin absolu : \}
(*
Cette procédure teste si à la position Pos de Ch on trouve le caractère '\'
Si OUI alors
Bon est mis à vrai
Pos est avancé d'autant que l'analyse en a eu besoin. Donc ici de +1
Sinon
Bon est mis à Faux
Pos est resté inchangé
*)
Begin
If Pos>Length(Ch) Then
Bon:=False
Else If Copy(Ch,Pos,1)<>'\' Then
Bon:=False
Else Begin
Bon:=True;
Pos:=Pos+1;
End;
End;
Figure A8.6. Ddétection d'indication de chemin absolu : \
Question 4
{On indique que la procédure Nom_Fichier sera utilisée avant d'être définie plus loin
(Forward), cf. question 5}
Procedure Nom_Fichier(Ch: string;Var Pos: integer; Var Bon:Boolean);forward;
(*******************)
Procedure SUITE_DIR(
Ch:String;
Var Pos: Integer;
Var Presence_Dir:Boolean);
{Détection d'une suite de noms de directories séparés par des \}
(*
Cette procédure teste si à partir de la position Pos de Ch on trouve une suite de noms
de directories séparés par des \. Voir diagramme de CONWAY de l'énoncé.
Si OUI alors
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
66
Bon est mis à vrai
Pos est incrémenté d'autant que l'analyse en a eu besoin.
Sinon
Bon est mis à faux
Pos est resté inchangé
*)
Var MemPos: integer;
{Mémorise la position de début d'analyse d'un
élément
pour permettre un retour arrière}
Bon : boolean;
(*++++++++++++*)
Procedure NOM_DIR(Ch:string; Var Pos: integer; Var Bon: Boolean);
{Test de présence de '.', '..' ou de nom de fichier}
(*
Cette sous-procédure teste si à la position Pos de Ch on trouve un nom de
directory, c'est-à-dire :
soit les caractères '..'
soit le caractère '.'
soit un nom de fichier
Si OUI alors
Bon est mis à vraie
Pos est avancé d'autant que l'analyse en a eu besoin.
Sinon
Bon est mis à false
Pos reste inchangé
*)
Begin
{Initialisation}
Bon:=False;
{Cas des caractères '..'}
If Pos+2<=Length(Ch) Then
If Copy(Ch,Pos,2)='..' Then Begin
Bon:=True;
Pos:=Pos+2;
End;
{Cas du caractère '.'}
If (Not Bon) and (Pos+1<=Length(Ch)) Then
If Copy(Ch, Pos, 1)='.' Then Begin
Bon:=True;
Pos:=Pos+1;
End;
{Cas d'une suite de caractères permis}
If Not Bon Then
Nom_Fichier(Ch, Pos, Bon);
end;
{DEBUT DE LA PROCEDURE PRINCIPALE SUITE_DIR}
Begin
{Initialisations}
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
67
\}
Presence_Dir:=False;
Bon:=True;
{Boucle de parcours à la recherche des noms de directories et des caractères
While Bon Do Begin
{Mémorisation de la position de début d'analyse du dernier
Nom de directory éventuellement rencontré}
MemPos:=Pos;
{Trouve-t-on un nom de directory ?}
Nom_Dir(Ch, Pos, Bon);
{Cas où on a trouvé un nom de directory : on poursuit l'analyse}
If Bon Then Begin
{Il n'ya pas la place pour le \ : pas bon}
If Pos>Length(Ch) Then
Bon:=False
{Ce n'est pas le caractère \ : pas bon}
Else If Copy(Ch,Pos,1)<>'\' Then
Bon:=False
{On a reperé une suite de noms de directory et de \}
Else begin (* égal donc à \ *)
{Pour "sauter" le caractère '\'}
Pos:=Pos+1;
{ Pour mémoriser que l'on a détecté au moins une directory}
Presence_Dir:=True;
End;
End;
End; {Fin du While}
{On est sorti de la boucle ==> échec. On retourne en arrière dans
l'analyse, pour revenir au dernier endroit sain}
Pos:=MemPos;
End;
Figure A8.7. Détection d'une suite de noms de directories séparés par des '\'
Question 5
(************************)
Procedure NOM_FICHIER(Ch: string; Var Pos: integer; Var Bon:Boolean);
{Vérification de la syntaxe d'un nom de fichier}
(*
Cette procédure teste si à la position Pos de Ch on trouve un nom de fichier DOS :
8 lettres au max suivi facultativement de '.' et d'un suffixe de 3 car. au max.
Si OUI alors
Bon est mis à vrai
Pos est avancé d'autant que l'analyse en a eu besoin.
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
68
Sinon
Bon est mis à false
Pos reste inchangé
*)
Var Fini : Boolean; {Variable de travail}
I : integer;
{Variable de travail}
Car : string[1]; {Variable de travail}
(*+++++++++++++*)
Function CAR_PERMIS(Car: string):Boolean;
{Test de la permision d'un caractère}
(*
Cette fonction renvoie VRAI si Car est un caractère permis.C'est-à-dire : 'A' à 'Z' ou 'a'
à 'z' ou '0' à '9' ou '_'
*)
Var Car2 : char; {Variable de travail}
Begin
If length(car)<>1 Then
Car_Permis:=False
Else Begin
Car2:=car[1];
Car_Permis:=( (Car2>='A') and (Car2<='Z') ) Or
( (Car2>='a') and (Car2<='z') ) Or
( (Car2>='0') and (Car2<='9') ) Or
( Car='_');
End;
End;
{DEBUT DE LA FONCTION NOM_FIC}
Begin
{***Test du nom proprement dit (sans suffixe)}
{Initialisations}
Fini:=False;
Bon:=true;
I:=0; {I représente la longueur du nom en cours de test}
{Boucle de parcours et d'analyse}
Repeat
{Cas où la fin de la chaîne est atteinte}
If Pos > Length(Ch) Then
Fini:=True
Else Begin
{Isolement du caractère courant}
Car:=Copy(Ch,Pos,1);
{Test de la validité du caractère courant}
If Not Car_Permis(Car) Then
Fini:=True
Else Begin
I:=I+1;
{Test si le nom n'a pas atteint le maximum de 8 caractères}
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
69
If I > 8 Then
Fini:=true
Else
{Passage à la position suivante}
Pos:=Pos+1;
End;
End;
Until Fini;
{Analyse de la longueur du nom}
If (I = 0) or (I > 8) Then
Bon:=False
Else Begin
{Test de l'éventuel suffixe}
If Pos<=Length(Ch) Then Begin
{Test du point séparateur entre le nom et le suffixe}
If Copy(Ch,Pos,1)='.' Then Begin
{Pour 'sauter' le caractère point}
Pos:=Pos+1;
{Initialisations}
Fini:=False;
I:=0;
{Boucle d'analyse du suffixe}
Repeat
{Test si on a pas atteint la fin de la chaîne}
If pos > Length(Ch) Then
Fini:=True
Else Begin
{Isolement du caractère courant}
Car:=Copy(Ch,Pos,1);
{Test de la validité du caractère courant}
If Not Car_Permis(Car) Then
Fini:=True
{Test si on a pas atteint le maximum de 3 caractères}
Else If I > 3 Then
Fini:=true
Else Begin
{Passage à la position suivante}
Pos:=Pos+1;
{Mise à jour de la longueur du suffixe}
I:=I+1;
End;
End;
Until Fini;
{Analyse de la longueur du suffixe}
If (I=0) or (I>3) Then
Bon:=False;
End; {Fin du If Copy(Ch,Pos,1)='.'}
End; {Fin du Pos<=Length(Ch)}
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
70
End; {Fin du Else}
End;
Figure A8.8. Sous-programme de vérification de la syntaxe d'un nom de fichier
Le lecteur désireux de tester le programme complet pourra saisir le programme
principal donné à la figure A8.9.
Program CHEMIN_DOS;
{Vérification de la syntaxe d'un chemin DOS}
(*
Le but de ce programme est de saisir une chaîne de caractères et d'analyser si celle-ci
représente un nom de fichier DOS. Le nom du fichier DOS s'entend au sens large
c'est-à-dire précédé ou non de son chemin
*)
Uses Dos,Crt;
Var
Ch : String; {Mémorise le nom de fichier à tester}
Pos : Integer; {Pointeur sur Ch, indique la position du prochain caractère à tester}
Presence_Lecteur : boolean;
{Variable de travail}
Presence_Absolu : boolean;
{Variable de travail}
Presence_Dir
: boolean;
{Variable de travail}
Presence_Fichier : boolean;
{Variable de travail}
{DEBUT DU PROGRAMME PRINCIPAL}
Begin
{Annonce du programme}
Clrscr;
Gotoxy(20,1); Write('Vérification d''un chemin DOS');
Gotoxy(20,2); Write('****************************');
Gotoxy(1,5); Write('EXEMPLES');
Gotoxy(1,8); Write('********');
Gotoxy(1,9); Write('C:\LISEZ.MOI');
Gotoxy(1,8); Write('PASCAL\CALCUL.PAS');
Gotoxy(1,9); Write('C:..\..\UTIL.DIR\CHAPITRE.1');
{Saisie de la chaîne à analyser}
Gotoxy(1,5); Write('Entrez le chemin à analyser:');
Readln(ch);
{Analyse de la chaîne entrée}
Pos:=1; (* Variable de parcours de la chaîne CH *)
Lecteur(Ch,Pos,Presence_Lecteur);
Slash(Ch,Pos,Presence_Absolu);
Suite_Dir(Ch, Pos, Presence_Dir);
Nom_Fichier(Ch, Pos, Presence_Fichier);
{Verdict de l'analyse}
Gotoxy(1,20);
If Presence_Lecteur Then
Writeln('Lecteur détecté !');
If Presence_Absolu Then
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
71
Writeln('Chemin absolu détecté !');
If Presence_Dir Then
WriteLn('Un ou plusieurs nom de directories détectés !');
If Presence_Fichier then {Le seul élément obligatoire dans un chemin est le }
{nom d'un fichier}
Writeln('Chemin correct !')
Else
Writeln('Erreur dans l''écriture du chemin DOS !');
End.
Figure A8.9. Exemple de programme principal
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
72
Annexe 9
Correction des exercices du chapitre 8
A9.1. PROBLEME 1 : TRADUCTION ANGLAISE
Question 1
Procedure RECHERCHE(Mot : string; Var Nos_Case : integer);
{Recherche du numéro de case d'un mot dans le vecteur Anglais}
Var Fini, Trouve : string;
Begin
{Initialisations}
Nos_Case:=1;
Fini:='FAUX';
Trouve:='FAUX';
{Boucle de parcours du vecteur Anglais}
While (Fini='FAUX') and (Trouve='FAUX') Do Begin
{Test si on a atteint la fin du vecteur{
If Nos_Case>Limit Then
Fini:='VRAI'
Else
{Test si on a trouvé le mot recherché}
If Anglais[Nos_Case]=Mot Then
Trouve:='VRAI'
Else
{Passage à la case suivante}
Nos_Case:=Nos_Case+1;
End; {fin du while}
End;
Figure A9.1. Recherche d'un mot dans le vecteur Anglais
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
73
Question 2
Procedure AJOUTER(Mot : string; Var Mot_Traduit : string);
{Ajout d'un
mot dans les vecteurs Anglais et Français}
Begin
{Saisie de la traduction anglaise}
Writeln('Traduction de ',Mot, ' inconnue, merci de la donner :');
Readln(Mot_Traduit);
{Test si il reste de la place dans le dictionnaire Anglais-Français}
If Limit>=100 Then
{Sortie d'un message d'avertissement}
Writeln('Dictionnaire plein : traduction non mémorisée !')
Else Begin
{Ajout proprement dit}
Limit:=Limit+1;
Anglais[Limit]:=Mot;
Francais[Limit]:=Mot_Traduit;
End;
End;
Figure A9.2. Ajout d'un mot dans le dictionnaire Anglais-Francais
Question 3
Procedure TRADUCTION(Mot : string; Var Mot_Traduit : string);
{Traduction d'un mot du français en anglais}
Var Nos_Case : integer;
Begin
{Recherche si le mot à traduire existe déjà dans le dictionnaire}
Recherche(Mot, Nos_Case);
{Cas où le mot n'est pas dans le dictionnaire}
If Nos_Case=Limit+1 Then
{Demande de la traduction du mot à l'utilisateur et ajout dans le dico}
Ajouter(Mot, Mot_Traduit)
Else
{Traduction automatique du mot à l'aide du dictionnaire}
Mot_Traduit:=Francais[Nos_Case];
End;
Figure A9.3. Traduction d'un mot du français en anglais
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
74
Question 4
Procedure MOT_SUIVANT(Ch : string; Var Mot : string; Var Pos : integer);
{Isolement du mot suivant dans la chaîne Ch à partir de la position Pos }
Var Car : string;
Fini, Trouve : string;
Begin
{Initialisations}
Fini:='FAUX';
Trouve:='FAUX';
{Boucle de parcours de la chaîne tant que l'on rencontre des blancs}
While (Fini='FAUX') and (Trouve='FAUX') Do Begin
{Test si on a atteint la fin de la chaîne}
If Pos>Length(Ch) Then
{La sentinelle Fini est mise à 'VRAI' ==> arrêt de la boucle}
Fini:='VRAI'
Else Begin
{Isolement du caractère courant}
Car:=Copy(Ch, Pos, 1);
{Cas où le caractère courant est dufférent de blanc}
If Car<>' ' Then
{La sentinelle Trouve est mise à 'VRAI' ==> arrêt de la boucle}
Trouve:='VRAI'
Else
{Passage à la position suivante de la chaîne}
Pos:=Pos+1;
End;
End;
{Initialisations}
Mot:='';
Trouve:='FAUX';
{Boucle de parcours du texte tant que l'on rencontre des caractères <> du
blanc}
While (Fini='FAUX') and (Trouve='FAUX') Do Begin
{Test si on a atteint la fin de la chaîne}
If Pos>Length(Ch) Then
{La sentinelle Fini est mise à 'VRAI' ==> arrêt de la boucle}
Fini:='VRAI'
Else Begin
{Isolement du caractère courant}
Car:=Copy(Ch, Pos, 1);
{Cas où le caractère courant est égal à blanc}
If Car=' ' Then
{La sentinelle Trouve est mise à 'VRAI' ==> arrêt de la boucle}
Trouve:='VRAI'
Else Begin {donc <> ' '}
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
75
{'accumulation' du caractère courant}
Mot:=Mot+Car;
{Passage à la position suivante de la chaîne}
Pos:=Pos+1;
End;
End;
End;
End;
Figure A9.4. Isolement du mot suivant, à partir de la position Pos, dans la chaîne Ch
Question 5
Program ANGLAIS_FRANCAIS;
{Programme principal de la traduction
anglais-français}
(*
En entrée : {Une chaîne de caractères censée représenter une phrase anglaise}
En sortie : {La traduction mot à mot en français de la phrase entrée avec une
mémorisation des différents mots traduits dans un système de deux variables
dimensionnées}
*)
Uses Dos, Crt;
Var Anglais : array[1..100] of string; {la partie anglaise du dictionnaire}
Francais: array[1..100] of string; {la partie fraçaise du dictionnaire}
Limit : integer; {le nombre de cases occupées dans Anglais[]}
ChAng, ChFra : string; {l'original anglais et sa traduction française}
Pos : integer; {La position courante dans ChAng}
Mot, Mot_Traduit : string;
Begin
{Entrée de la phrase anglaise à traduire}
Writeln('Entrez la phrase anglaise à traduire :');
Readln(ChAng);
{Initialisations}
Limit:=0; {le dictionnaire est vide}
Pos:=1; {on commence le parcours au premier caractère de ChAng}
ChFra:='';
{Boucle de parcours de la phrase anglaise pour traduction}
While Pos<=Length(ChAng) Do Begin
{Isolement du mot anglais suivant}
Mot_Suivant(ChAng, Mot, Pos);
{On a isolé un mot anglais}
If Mot<>'' Then Begin
{Traduction du mot anglais avec éventuellemnt enrichissement du
dictionnaire}
Traduction(Mot, Mot_Traduit);
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
76
{Ajout du mot traduit à la phrase résultat}
ChFra:=ChFra+Mot_Traduit+' ';
End;
End; {Fin du While}
{Sortie du résultat}
Writeln('On obtient la traduction : ', ChFra);
End.
Figure A9.5. Programme principal de la traduction anglais-français
A9.2. PROBLEME 2 : LE JEUX DE LA VIE
Question 1
La cellule (4, 6) restera à l'état mort car elle possède 4 voisins vivants.
La cellule (6, 5) passera à l'état mort car elle possède 5 voisins vivants.
La cellule (8, 5) restera à l'état mort car elle possède un seul voisin vivant.
La cellule (9, 3) passera à l'état vivant car elle possède 2 voisins vivants.
Question 2
Procedure INIT_BLANC;
{Initialisation à blanc de toutes les cases du
tableau Damier}
Var i, j : integer;
Begin
{Boucle de parcours des lignes de Damier}
For i:=1 to 10 Do
{Boucle de parcours des colonnes de Damier}
For j:=1 to 10 Do
{Mise à blanc de la case i, j de Damier}
Damier[i, j]:=' ';
End;
Figure A9.6. Initialisation à blanc de toutes les cases du tableau Damier
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
77
Question 3
Procedure INIT_COORDONNEES;
{Saisie par l'utilisateur des
coordonnées des cellules vivantes}
Var i, j : integer;
Continue : Char;
Begin
{Initialisation}
Continue:='O';
{Boucle de demandes répétées de saisie de coordonnées }
While Continue='O' Do Begin
{Demande à l'utilisateur s'il veut continuer la saisie de coordonnées{
WriteLn('Voulez-vous entrer une coordonnée de cellule vivante (O-N) :');
ReadLn(Continue);
Continue:=UpCase(Continue);
{Test si l'utilisateur veut continuer}
If Continue='O' Then Begin
{Saisie d'une paire de coordonnées}
Writeln('Entrez le numéro de ligne : ');
Readln(i);
Writeln('Entrez le numéro de colonne : ');
ReadLn(j);
{Test de la validité des coordonnées saisies}
If (i<1) or (i>10) or (j<1) or (j>10) Then
{Sortie d'un message d'erreur}
Writeln('Coordonnées incorrectes !')
Else
{Initialisation de la case correspondante dans Damier}
Damier[i, j]:='*';
End;
End; {Fin du While}
End;
Figure A9.7. Saisie par l'utilisateur des cordonnées des cellules vivantes
Question 4
Procedure SORTIR_DAMIER;
{Affichage à l'écran du damier}
Var i, j : integer;
Begin
{Boucle de parcours des lignes du damier}
For i:=1 to 10 Do Begin
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
78
{Boucle de parcours des colonnes du damier}
For j:=1 to 10 Do Begin {Begin-End facultatif}
{Affichage de la case courante du damier}
Write(Damier[i, j]); {Write sans le 'Ln' ne passe pas à la ligne suivante}
End;
{Passage à la ligne suivante de l'écran}
Writeln;
End;
End;
Figure A9.8. Affichage à l'écran du damier
Question 5
Procedure NOMBRE_VOISIN(i, j : integer; Var Voisin : integer);
{Calcul
du nombre de voisins vivants de la cellule i, j du damier}
Var IPrime, JPrime : integer;
Begin
{Initialisation du compteur du nombre de voisins vivants}
Voisin:=0;
{Boucle de parcours des lignes avant et après celles de I}
For Iprime:=i-1 to i+1 Do
{Boucle de parcours des colonnes avant et après celles de J}
For JPrime:=j-1 to j+1 Do Begin {Begin-End facultatif}
{La coordonnée a tester est-elle dans le damier }
If (IPrime>=1) and (IPrime<=10) and
(JPrime>=1) and (JPrime<=10) Then
If Damier[IPrime, JPrime]='*' then
{Mise à jour du compteur du nombre de voisins vivants}
Voisin:=Voisin+1;
End;
{Test si la boucle a compté Damier[i, j] comme voisin donc en trop}
If Damier[i, j]='*' Then
Voisin:=Voisin-1;
End;
Figure A9.9. Calcul du nombre de voisins vivants de la cellule i, j du damier
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
79
Question 6
Procedure TRANSFERT(Damier1:Tdamier; Var Damier2:TDamier);
{Copie du contenu du damier Damier1 vers le damier Damier2}
Var i, j : integer;
Begin
{Boucle de parcours des lignes de Damier1}
For i:=1 to 10 Do
{Boucle de parcours des colonnes Damier1}
For j:=1 to 10 Do
{Copie de la cas courante de Damier1 vers celle de Damier2}
Damier2[i, j]:=Damier1[i, j];
End;
Figure A9.10. Copie du contenu du damier Damier1 vers le damier Damier2
Question 7
Procedure GENERATION_SUIVANTE;
{Calcul de la génération
suivante du damier}
Var i, j, Voisin : integer;
Damier2 : Tdamier;
Begin
{Boucle de parcours des lignes du damier}
For i:=1 to 10 Do
{Boucle de parcours des colonnes du damier}
For j:=1 to 10 Do Begin
{Calcul du nombre de voisins vivants de la cellule courante du damier}
Nombre_Voisin(i, j, Voisin);
{Cas où la cellule reste ou devient vivante}
If (Voisin=2) or (Voisin=3) Then
{Mise à 'vivant' de la cellule dans le damier de travail}
Damier2[i, j]:='*'
Else
{Mise à 'mort' de la cellule dans le damier de travail}
Damier2[i, j]:=' ';
End;
{Transfert du damier de calculé dans le damier initial}
Transfert(Damier2, Damier);
End;
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
80
Figure A9.11. Calcul de la génération suivante du damier
Question 8
Program JEUX_DE_LA_VIE;
{Programme permettant de jouer au jeu de
la vie}
{ Le but de ce programme est de permettre de jouer au jeux de la vie sur un
damier 10x10. }
Uses Dos, crt;
Type TDamier = array[1..10, 1..10] of char; {pour résoudre problème de passage de
paramètre}
Var Damier : TDamier;
{Le damier de jeux}
N : integer;
{Le nombre de générations demandées par
l'utilisateur}
Nos_Generation : integer;{Compteur du nombre de génération}
Continue : char;
{Variable de travail}
Begin
{Initialisation à blanc des cases du damier}
Init_Blanc;
{Saisie des coordonnées des cellules vivantes}
Init_Coordonnees;
{Saisie du nombre de générations à produire}
Writeln('Entrez le nombre de génération à produire :');
Readln(N);
{Autres initialisations}
Nos_Generation:=0;
Continue:='O';
{Boucle de construction des générations}
While (Nos_Generation<N) and (Continue='O') Do Begin
{Affichage du damier}
Sortir_Damier;
{Mise à jour du compteur de générations}
Nos_Generation:=Nos_Generation+1;
Writeln('Génération ', Nos_Generation:3);
{Test s'il reste des générations à calculer}
If Nos_Generation<N Then Begin
{Demande à l'utilisateur s'il veut continuer}
Writeln('Voulez-vous continuer (O-N) :');
Readln(Continue);
Continue:=UpCase(Continue);
{Cas où l'utilisateur veut continuer}
If Continue='O' Then
{Calcul de la génération suivante}
Generation_Suivante;
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
81
End;
End; {Fin du While}
End.
Figure A9.12. Programme permettant de jouer au jeux de la vie
A9.3. PROBLEME 3 : L'INDEX DE LIVRE
Préliminaires
Le programme de la figure A9.13 est un exemple de programme principal
(question non demandée dans l'énoncé) utilisant les procédures des différentes
questions
Program P_INVERSE;
{Exemple de programme utilisant un index de
livre}
{
Il s'agit d'entrer une suite de mots dans le tableau Texte; puis de remplir les tableaux
Dico et Inverse de sorte que ces deux tableaux forment un fichier inverse au sens de
l'informatique documentaire (à comparer à un index de fin de livre). Pour plus de
précisions, voir le texte de l'énoncé du problème.
Avertissement : les tableaux Texte, Dico et Inverse ne sont jamais passés en paramètres
des différentes procédures. Ils sont systématiquement utilisés en variables globales
}
Uses
Dos, Crt;
Const
{Taille pour différents tableaux, notamment le tableau Texte}
Taille_Vecteur = 100;
Type
T_Texte = array[1..Taille_Vecteur] of string[30];
T_Dico = array[1..Taille_Vecteur] of string[30];
T_Inverse = array[1..Taille_Vecteur,1..20] of integer;
Var
Texte : T_Texte; {Le texte à traiter entré par l'utilisateur : un mot par case}
Dico : T_Dico; {Le dictionnaire des mots de TEXTE
}
Inverse : T_Inverse;
{Pour chaque mot de Dico, la liste des places où ce mot
apparaît dans Texte}
Mot : string;
Begin
{Saisie des mots à référencer}
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
82
Remplir_Texte;
{Constitution des fichiers inverses}
Creation_Inverse;
{Initialisation}
Mot:='';
{Utilisation pour test des fichiers inverses}
While Mot<>'*' Do Begin
{Saisie du mot à rechercher}
Writeln('Entrez le mot à rechercher :');
Readln(Mot);
{L'utilisateur à entrer '*' : il veut arrêter}
If Mot<>'*' Then
{Affichage de la liste des références trouvées pour Mot}
Affiche_Liste_Reference(Mot);
End;
End.
Figure A9.13. Exemple de programme utilisant un index de livre
Question 1
On obtient la figure A9.14.
DICO
MOT2
MOT1
MOT3
*
?
?
1
3
4
0
0
0
2
6
5
?
?
?
INVERSE
7
0
0
?
8
0
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
Figure A9.14. Exemple d'index
Question 2
Procedure REMPLIR_TEXTE;
{Saisie d'une liste de mots}
{
Cette procédure saisit une liste de chaînes de caractères terminée par le caractère '*' et
en garnit le tableau TEXTE ( y compris le caractère *'')
}
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
83
Var NosMot : integer;
{Numéro du prochain mot à saisir}
Mot : string;
{Variable de travail
}
Begin
{Initialisations}
Gotoxy(15,1); Writeln('Saisie du texte à analyser');
Gotoxy(15,2); Writeln('**************************');
Nosmot:=1;
{Boucle de saisie des mots à traiter}
Repeat
{Saisie du mot}
Gotoxy(1,5); Clreol; {Effacement de la ligne avant saisie}
Gotoxy(1,5); Write('Entrez votre mot numéro ',NosMot:3,' {=arrêt) : ');
Gotoxy(41,5); Readln(Mot);
{Mémorisation dans le vecteur Texte}
Texte[NosMot]:=Mot;
{Mise à jour du compteur de mots}
NosMot:=NosMot+1
Until (Mot='*') or (NosMot=Taille_Vecteur);
{Si la boucle de saisie s'est terminée faute de place dans le tableau Texte,
alors on impose que le tableau Texte se termine par '*'}
If Mot<>'*' Then
Texte[NosMot]:='*';
End;
Figure A9.15. Saisie d'une liste de mots
Question 3
Procedure RECH_DICO(Mot::string; Var Place:integer);
{Recherche
d'un mot dans le dictionnaire}
{
Cette procédure recherche si Mot se trouve dans le tableau Dico
Si OUI alors
Place mémorise sa place dans Dico
Sinon
Place mémorise la case où se trouve le caractère '*' qui sert de marqueur de la fin
pour Dico
}
Var Fini : boolean; {Variables de travail}
Trouve: boolean;
Begin
{Initialisations}
Fini:=False;
Trouve:=False;
Place:=1;
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
84
{Boucle de parcours du dictionnaire}
Repeat
{Test si on atteint la fin du dictionnaire}
If Dico[Place]='*' Then
Fini:=True
{Test si on a trouvé le mot recherché}
Else If Dico[Place]=Mot Then
Trouve:=True
Else
{Passage au numéro de case suivant}
Place:=Place+1;
Until (Trouve) or (Fini);
End;
Figure A9.16. Recherche d'un mot dans le dictionnaire
Question 4
Procedure RECH_FIN_INVERSE( Ligne : integer; Var Last_Place: integer);
{Recherche de la valeur zéro dans une ligne du tableau Inverse}
{
Cette procédure recherche dans la ligne Ligne du tableau Inverse, la place du marqueur
de fin de liste (i.e. 0). Celle-ci est retournéedans le paramètre Last_Place
}
Var i : integer;
Fini : boolean;
Begin
{Initialisations}
Fini:=False;
Last_Place:=1;
{Boucle de parcours de la ligne Ligne du tableau Inverse}
While Inverse[Ligne,Last_Place]<>0 Do
{Passage à la case suivante}
Last_Place:=Last_Place+1;
End;
Figure A9.17. Recherche de la valeur zéro dans une ligne du tableau Inverse
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
85
Question 5
Procedure AFFICHE_LISTE_REFERENCE (Mot: : string);
{Affichage
des références d'un mot}
{
Cette procédure affiche la liste des références de Mot dans Texte. Cependant la
recherche est faite sans utiliser Texte mais en utilisant à Dico et Inverse
}
Var
Place_Dico : Integer;
I : integer;
Begin
{Recherche dans le dictionnaire de la place de Mot}
Rech_Dico(Mot, Place_Dico);
{Cas où le Mot n'est pas présent dans le dictionnaire }
If Dico[Place_Dico]='*' then
{Affichage d'un message d'erreur}
Write(Mot,' est inconnu !')
{Affichage des références demandées par parcours de la ligne
Place_Dico du tableau Inverse}
Else Begin
{Initialisation}
I:=1;
{Boucle de parcours de la ligne Inverse correspond à Mot}
While Inverse[Place_dico,i]<>0 Do Begin
{Affichage de la référence courante}
Writeln('La référence ', I:2, ' de ', Mot, ' se trouve à la case ',
'numéro : ',Inverse[Place_Dico,i],' de TEXTE');
{Passage à la case suivante de Inverse}
i:=i+1;
End; {Fin du While}
End;
End;
Figure A9.18. Affichage des références d'un mot
Question 6
Procedure CREATION_INVERSE;
livre}
{
{Création complète d'un index de
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
86
Création des tableaux Mot et Inverse à partir du tableau Texte. Cf. l'énoncé du problème
pour plus de détail.
}
Var i : integer;
Place_Dico, Last_Place_Inverse : integer;
Fini : Boolean;
Begin
{Initialisation des tableaux Dico et Inverse}
Dico[1]:='*';
For i:=1 to Taille_Vecteur Do
Inverse[i,1]:=0;
{Initialisation de la variable de parcours du tableau Texte}
I:=1;
{Boucle de parcours de Texte pour remplir Dico et Inverse}
Repeat
{Test si on a atteint la fin du texte à traiter}
If Texte[i]='*' Then
Fini:=True
Else Begin
{Recherche de la place du mot texte[i] dans le dictionnaire}
Rech_Dico(Texte[i], Place_Dico);
{Cas où le dictionnaire est plein}
If Place_Dico=Taille_Vecteur Then Begin
{Affichage d'un message d'erreur}
Write('Dictionnaire plein !!');
{Mise à vrai de la sentinelle Fini ==> fin la boucle}
Fini:=True;
{Cas particulier où il faut en plus ajouter avant le mot dans le
dictionnaire}
End Else If Dico[Place_Dico]='*' then Begin
Dico[Place_Dico+1]:='*';
Dico[Place_Dico]:=Texte[i];
Inverse[Place_dico,1]:=i; {mot nouveau => première référence pour
Inverse}
Inverse[Place_Dico,2]:=0;
{Cas général : ajout d'un référence dans Inverse}
End Else begin
{Recherche de la dernière case occupée dans la ligne Place_Dico de
Inverse
Rech_Fin_Inverse(Place_Dico, Last_Place_Inverse);
{Trop de références pour le texte[i]}
If Last_Place_Inverse=50 Then Begin
{Affichage d'un message d'erreur}
Write('Table INVERSE pleine !');
{Mise à vrai de la sentinelle Fini : fin la boucle}
Fini:=true;
{Ajout en fin de ligne de Inverse de la référence}
End Else Begin
Inverse[Place_Dico,Last_Place_Inverse]:=i;
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
87
Inverse[Place_Dico,Last_Place_Inverse+1]:=0;
End;
End;
End;
{Passage à la case suivante de Texte}
i:=i+1;
Until Fini;
End;
Figure A9.19. Création complète d'un index de livre
A9.4. PROBLEME 4 : LA TABLE DES SYMBOLES
Préliminaires
Le programme de la figure A9.19 et les procédures de la figure A9.221 forment
est un exemple de programme principal (question non demandée) utilisant les
procédures des différentes questions.
Program TABLE_DES_SYMBOLES;
{Exemple de programme utilisant
les procédures demandées}
{
Le but de ce programme est d'être une petite illustration de la gestion de la table des
symboles utilisée lors d'une compilation.
}
Uses
Dos, Crt;
Var
{Déclaration de la table des symboles}
TNom : array[1..1000] Of Char;
TSym1 : array[1..100] Of integer;
TSym2 : array[1..100] Of String[30];
{Variables de travail}
Position : integer;
Begin
{Annonce du programme à l'utilisateur}
Clrscr;
Gotoxy(1,5); Writeln('Programme de test pour la gestion d''une table de symbole');
Gotoxy(1,6);
Writeln('*********************************************************');
Suite; {Attente qu'une touche soit frappée par l'utilisateur}
Gotoxy(1,8);
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
88
Writeln('Etat de la table de symbole vide :');
Writeln;
{Initialisation à vide de la table des symboles}
Init;
{Affichage pour contrôle de la table des symboles}
Affiche;
{Attente qu'une touche soit frappée par l'utilisateur}
Suite;
{Mise au courant de l'utilisateur du test 1 d'ajout dans la table des
symboles}
Gotoxy(1,8);
Writeln('Ajout de la variable CARCOUR de type CHAINE DE ',
'CARACTERES :');
Writeln;
{Réalisation effective du test}
If Ajout('CARCOUR','CHAINE DE CARACTERES')='VRAI' Then
{Affichage de la table des symboles pour contrôle }
Affiche;
Suite;
{Mise au courant de l'utilisateur du test 2 d'ajout dans la table des
symboles}
Gotoxy(1,8);
Writeln('Ajout de la variable TOTAL de type NUMERIQUE :');
Writeln;
{Réalisation effective du test}
If Ajout('TOTAL','NUMERIQUE')='VRAI' Then
{Affichage de la table des symboles pour contrôle }
Affiche;
Suite;
{Mise au courant de l'utilisateur du test 3 d'ajout dans la table des
symboles}
Gotoxy(1,8);
Writeln('Ajout de la variable CH de type CHAINE DE CARACTERE :');
Writeln;
{Réalisation effective du test}
If Ajout('CH','CHAINE DE CARACTERES')='VRAI' Then
{Affichage de la table des symboles pour contrôle}
Affiche;
Suite;
{Mise au courant de l'utilisateur du test 1 de recherche d'un nom de variable
dans la table des symboles}
Gotoxy(1,8);
Writeln('Affichage de la position de la variable CARCOUR dans TSYM : ');
{Réalisation effective du test}
Recherche('CARCOUR',position);
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
89
{Affichage du résultat de la recherche }
Writeln(position); Writeln;
{Affichage de la table des symboles pour contrôle}
Affiche;
Suite;
{Mise au courant de l'utilisateur du test 2 de recherche d'un nom de variable
dans la table des symboles}
Gotoxy(1,8);
Writeln('Affichage de la position de la variable TOTAL dans TSYM : ');
{Réalisation effective du test}
Recherche('TOTAL', position);
{Affichage du résultat de la recherche }
Writeln(position); Writeln;
{Affichage de la table des symboles pour contrôle}
Affiche;
Suite;
{Mise au courant de l'utilisateur du test 3 de recherche d'un nom de variable
dans la table des symboles}
Gotoxy(1,8);
Writeln('Affichage de la position de la variable CH dans TSYM : ');
{Réalisation effective du test}
Recherche('CH', position);
{Affichage du résultat de la recherche }
Writeln(position); Writeln;
{Affichage de la table des symboles pour contrôle}
Affiche;
Suite;
End.
Figure A9.20. Exemple de programme utilisant les procédures demandées
Procedure AFFICHE;
{Affichage de la table des symboles, c'est-à-dire les
tableaux TSym&, TSym2 et TNom}
Var Finnom, FinSym : integer;
Begin
{Initialisations}
Writeln('Tableau TSYM1 et TSYM2 : ');
FinSym:=0;
{Boucle de parcours pour afficher les tableaux Tsym1 et TSym2
respectivement la table des pointeurs vers TNom et la table des types des
variables}
Repeat
{Passage à la case suivante}
FinSym:=FinSym+1;
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
90
{Cas où la case de TSym1[FinSym]<>0 alors TSym2[Tsym] mémorise
le type de la variable pointée par TSym1[FinSym]}
If TSym1[FinSym]<>0 Then
Writeln(TSym1[FinSym]:3, ' ', Tsym2[FinSym])
Else
{On affiche le zéro pour contrôle}
Writeln(TSym1[FinSym]:3);
until TSym1[FinSym]=0;
Writeln;
{Initialisations}
Write('Tableau TNOM :');
FinNom:=0;
{Boucle de parcours pour afficher les cases de TNom : la suite des lettres
composant les noms de variables mémorisée}
Repeat
{Passage à la case suivante}
FinNom:=FinNom+1;
{Affichage de la lettre courante}
Write(Tnom[FinNom]);
until Tnom[FinNom]='#';
End;
Procedure Suite;
{Procédure-utilitaire d'attente}
Var Rep : string;
Begin
{Attente qu'une touche soit frappée par l'utilisateur}
Gotoxy(1,22);
Writeln('Appuyez sur une touche pour continuer !');
ReadLn(Rep);
{Effacement de l'écran}
ClrScr;
End;
Figure A9.21. Procédures complémentaires pour le programme principal de la figure A9.20
Question 1
Les vecteurs TSym1 et TSym2 possèdent chacun 1000 cases, mais comme il faut
réserver une case pour le marqueur de fin (le 0 dans TSym1), la table des symboles
présentée ne pourra au maximum mémorisée que 999 variables.
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
91
Question 2
On obtient le schéma de la figure A9.21.
D E F N O M * D E F P R E N O M * D E F R U E #
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
1
8
18
0
?
"Chaîne de caractères"
"Chaîne de caractères"
"Chaîne de caractères"
?
?
.
.
.
?
?
?
TSYM1
.
.
.
?
?
TSYM2
Figure A9.22. La table des symboles
Question 3
Procedure INIT;
{Initialisation à vide de la table des symboles}
Begin
{Initialisation de la table des pointeurs vers la table TNom}
TSym1[1]:=0;
{Initialisation (facultative) de la table (des lettres) des noms de variables}
TNom[1]:='#';
End;
Figure A9.23. Initialisation à vide de la table des symboles
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
...
...
92
Question 4
Procedure RECUP_NOM(
PosNom: integer;
Var Nom : string );
{Récupération d'un nom de variable à partir de sa position dans TNom}
{
En début de procédure PosNom pointe sur une case de TNom dans laquelle débute la
mémorisation d'un nom de variable. En fin de procédure, Nom mémorise le nom
pointé par PosNom.
}
Var
Fini : boolean;
i : integer;
Begin
{Initialisations}
Fini:=False;
i:=posnom;
nom:='';
{Boucle de parcours de TNom pour reconstituer le nom de variable}
Repeat
{Test de présence d'un marqueur de fin de nom de variables ou de fin
de table}
If (tnom[i]='*') or (tnom[i]='#') Then
Fini:=True
Else begin
{Accumulation de la lettre courante pour former le nom de variable}
nom:=nom+tnom[i];
{Passage à la case suivante de TNom}
i:=i+1;
End;
Until Fini;
End;
Figure A9.24. Récupération d'un nom de variable à partir de sa position dans TNom
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
93
Question 5
Procedure RECHERCHE(
Nom : string;
Var Position : integer);
{Recherche de l'entrée d'une variable dans TSym1 à partir de son nom}
{
En début de procédure Nom contient un nom de variable à retrouver dans la table des
symboles. En fin de procédure :
Si Nom se trouve dans la table des symboles alors
Position mémorise le numéro de case de TSym1 qui pointe sur la position de TNom
où se trouve Nom;
sinon
Position est mis à zéro.
}
Var
Fini : boolean;
Trouve : boolean;
Nom_candidat : string;
Begin
{Initialisations}
Fini:=False;
Trouve:=false;
Position:=1;
{Boucle de parcours de TSym1 à la recherche de l'entrée}
Repeat
{Test si on a atteint la fin de la table TSym1}
If tsym1[position]=0 Then
Fini:=True
Else begin
{Récupération du nom de la variable pointée par TSym1[Position]}
Recup_nom(tsym1[position], nom_candidat);
{Test s'il s'agit du nom recherché}
If nom=nom_candidat Then
Trouve:=true
Else
{Passage à la case suivante de TSym1}
position:=position+1;
End;
Until (Trouve) or (Fini);
{Cas où le parcours s'est terminé sans avoir trouvé la variable recherchée}
If not Trouve Then
Position:=0;
End;
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
94
Figure A9.25. Recherche de l'entrée d'une variable dans TSym1 à partir de son nom
Question 6
Function AJOUT(Nom, Typ : string):string;
{Ajout d'une variable dans la
table des symboles}
{
Cette fonction ajoute dans la table des symboles la variable de nom Nom et de type
Typ. Elle renvoie 'VRAI' si l'ajout a pu se faire et 'FAUX' sinon (cas de table des
symboles pleine).
}
Var
Fini, Trouve : boolean;
Position : integer;
FinNom : integer;
DebutNom : integer;
FinSym : integer;
i : integer;
Begin
{Initialisation}
FinNom:=0;
{Boucle de recherche de la fin de liste de TNom (on va y faire l'ajout
du nom)}
Repeat
{Passage à la case suivante}
FinNom:=FinNom+1
until Tnom[FinNom]='#'; {# : marqueur de fin de liste de TNom}
{Cas où il ne reste pas assez de place dans TNom pour effectuer l'ajout}
If FinNom+Length(nom)>10000 Then {TNom possède 10000 cases}
Ajout:='FAUX'
Else Begin
{Initialisation}
FinSym:=0;
{Boucle de recherche de la fin de la liste dans TSym1 (on va y mémorisé
le pointeur vers TNom}
Repeat
{Passage à la case suivante}
FinSym:=FinSym+1
until Tsym1[FinSym]=0; {0 est la marqueur de fin de liste de TSym1}
{Cas où TSym1-TSym2 sont pleins}
If FinSym>=1000 Then {TSym1 possède 1000 cases}
Ajout:='FAUX'
Else Begin
If FinNom<>1 Then Begin
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
95
{Mémorisation de '*' pour séparer le nom que l'on va insérer du
nom précédent. Mais à ne pas faire pour de l'ajout du premier nom
puisque que celui-ci n'a pas de précédent}
Tnom[FinNom]:='*';
FinNom:=FinNom+1;
End;
{Mémorisation de la case du début d'ajout dans TNom}
DebutNom:=FinNom;
{Boucle d'ajout du nom dans TNom à raison d'une lettre par case}
For i:=1 to length(nom) do begin
tnom[FinNom]:=nom[i];
FinNom:=FinNom+1;
End;
{Pose du marqueur de fin pour TNom}
tnom[FinNom]:='#';
{Référencement dans TSym1 et TSym2}
Tsym1[FinSym]:=DebutNom;
Tsym2[FinSym]:=typ;
Tsym1[FinSym+1]:=0;
Ajout:='VRAI';
End;
End;
End;
Figure A9.26. Ajout d'une variable dans la table des symboles
A9.5. PROBLEME 5 : JUSTIFICATION D'UN TEXTE
Question 1
La
justification
de
la
chaîne
de
29
caractères
‘A . AA . AAAAAAAAAAA . A . A . AAAAAAA’, donnera les 4 sous-chaînes :
Les lignes
produites
‘A . . . . . . . AA . ’
Commentaires
La mise du mot "AAAAAAAAAAA" dans cette première ligne
aurait produit une ligne de 17 caractères. Donc ce mot a été
reporté à la ligne suivante. Ce report produit la ligne "A . . AA . "
de 6 caractères dans laquelle le caractère différent de blanc le plus
à droite se trouve en position 5. Ainsi pour le faire décaler à la
position 10 : 5 blancs ont été ajoutés à la fin du premier mot.
‘AAAAAAAAAA’ Le mot "AAAAAAAAAAA" fait plus de dix caractères, il a été
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
96
mis à cheval sur deux lignes. Les 10 premiers caractères sur cette
ligne et le reste, un caractère, a été mis sur la ligne suivante.
‘A . . . . A . . . A. . ’ La mise du mot "AAAAAAA" aurait produit une ligne de 13
caractères. Donc ce mot a été reporté à la ligne suivante. A la suite
de ce report on obtient la ligne de "A . A . A . " de 6 caractères
dans laquelle le caractère différent de blanc le plus à droite se
trouve à la position 5. Ainsi pour le faire décaler à la position 10,
5 blancs ont été ajoutés : trois blancs à la fin du premier mot et
deux blancs à la fin du second..
‘AAAAAAA’
S’agissant de la dernière ligne, elle n’a pas été complétée à 10
caractères, mais laissée telle quelle.
Figure A8.10. La justification de texte
Question 2
Function MEME_TYPE(Car1,car2: string) : boolean;
{Retourne Vrai si CAR1 et CAR2 sont de même "type"}
Begin
Meme_type:=False;
If (Car1=' ') and (Car2=' ') Then Meme_Type:=True;
If (Car1<>' ') and (Car2<>' ') Then Meme_type:=True;
End;
Figure A8.11. La fonction Même_type
Question 3
Procedure SEQUENCE_SUIVANTE(
Texte : string;
Var Copie_de_I : integer;
Var Next_Seq : string);
(*
Mémorise dans Next_Seq ce qu'on trouve à la position I de Texte parmi :
. Un mot
. Une séquence de blancs
*)
Var
WFin
: Boolean; (* Variables de travail *)
CarPrem : String;
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
97
CarCour : String;
Begin
{Mémorisation du premier caractère}
CarPrem:=Copy(Texte, Copie_De_I , 1);
{Initialisation du buffer pour mémoriser la prochaîne séquence}
Next_Seq:='';
WFin:=False;
{Boucle de récupération de l'entité : mot ou séquence de blancs}
Repeat
{Test si on a pas dépassé la fin de la chaîne}
If Copie_De_I>length(Texte) Then WFin:=True
Else Begin
{Isolement du caractère courant}
CarCour:=Copy(Texte, Copie_De_I, 1);
{Test si on a une rupture blanc et non blanc}
If Not Meme_Type(CarPrem,CarCour) Then WFin:=True
Else Begin
{Passage au suivant}
Next_Seq:=Next_Seq+CarCour;
Copie_De_I:=Copie_De_I+1;
End;
End;
Until WFin;
End;
Figure A8.12. La procédure Sequence_Suivante
Question 4
Procedure DECOMPOSE(
Texte : string;
I : integer;
Var Structure : TStruct);
(*
Cette procédure décompose Texte, à partir de sa position I, en une suite de mots et
séquences de blancs. Cette décomposition est mémorisée dans Structure. La capacité de
Structure est limitée à dix (mots ou séquences de blancs)
*)
Var
Wi : integer;{Variables de travail}
Copie_De_I : integer;
Nb_Sequence : Integer;
SeqCour : string;
Begin
{Raz de Structure}
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
98
For Wi := 1 to 10 Do Structure[Wi]:='';
{Pour ne pas oublier que I est passée par valeur}
Copie_De_I:=I;
Nb_Sequence:=0;
{Boucle de remplissage de Structure : 1 tour de boucle ==> 1 case de
remplie}
While (Copie_De_I <= Length(Texte)) and (Nb_Sequence<10) Do Begin
{Récupération de la séquence suivante : un mot ou une séquence de
blancs}
Sequence_Suivante(Texte, Copie_De_I, SeqCour);
{Mise à jour du compteur de séquence}
Nb_Sequence:=Nb_Sequence+1;
{Mémorisation dans Structure de la séquence isolée}
Structure[Nb_Sequence]:=SeqCour;
End;
End;
Figure A8.13. La procédure Decompose
Question 5
Procedure PRE_CALCUL(
Var Structure : TStruct;
Var NbMots, PosLastCar : integer);
(*
Cette procédure élimine de Structure les cases qui ne pourront tenir dans la prochaîne
ligne justifiée. De plus, elle mémorise dans NbMots le nombre de mots restant dans
Structure et dans Pos_LastCar la position du dernier caractère de Texte différent de
blanc restant dans Structure.
*)
Var
WLigne : string; {Variables de travail}
NbCase : integer;
WFin : boolean;
Future_Ligne : string;
Wi : integer;
Begin
{Initialisations}
WLigne:=''; NbCase:=0; WFin:=False;
NbMots:=0; PosLastCar:=0;
{Boucle de parcours des cases de Structure}
Repeat
{Test si on a parcouru toutes les 10 cases de Structure}
If NbCase>=10 Then WFin:=True
Else Begin
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
99
{Passage à la case suivante de Structure}
NbCase:=NbCase+1;
{Une case vide ==> on atteint la dernière case remplie de Structure}
If Structure[NbCase]='' Then Begin
WFin:=True
{La case courante de Structure mémorise une séquence de caractères}
End Else Begin
{Si le premier caractère est <>blanc alors la case mémorise un mot}
If Copy(Structure[NbCase],1,1)<>' ' Then Begin
{On essaye d'ajouter le mot rencontré dans la WLigne}
Future_Ligne:=WLigne+Structure[NbCase];
{Cas où le mot que l'on vient de rencontrer fait déborder Wligne}
If Length(Future_Ligne)>10 Then Begin
WFin:=True;
{Cas d'une ligne d'un seul mot de plus de 10 caractères}
If NbCase=1 Then Begin
WLigne:=Copy(Future_Ligne,1,10);
Structure[NbCase]:=WLigne;
PosLastCar:=Length(WLigne);
NbMots:=NbMots+1;
NbCase:=NbCase+1
End;
{Elimination des cases inutiles dans Structure}
For Wi:=NbCase to 10 Do Structure[Wi]:='';
{Cas où le mot que l'on vient de rencontrer peut tenir dans
Wligne}
End Else Begin
WLigne:=Future_Ligne;
PosLastCar:=Length(WLigne);
NbMots:=NbMots+1;
End;
{La case courante de Structure mémorise une séquence de blancs *)
End Else Begin
WLigne:=WLigne+Structure[NbCase];
End;
End;
End;
Until WFin;
End;
Figure A8.14. La procédure Pre_Calcul
Question 6
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
100
Procedure INTERCALAIRE(
NbMots : integer;
PosLastCar : integer;
Var Blanc : string;
Var BlancSup : integer );
(*
Cette procédure calcule les données suivantes :
. Blanc : séquence de blancs à ajouter à la fin de chaque de mots en vue d'obtenir la
justification.
. BlancSup : Nombre de fin de mots qui doivent recevoir un blanc de plus.
*)
Var ManqueBlanc : integer; {Variables de travail}
TailleBlanc : integer;
Begin
{Cas spécial : ligne de blancs ou ligne ne contenant qu'un seul mot}
If NbMots<=1 Then Begin
Blanc:='';
BlancSup:=0;
End Else Begin
{Calcul du nombre de caractères manquants pour obtenir 10 caractères}
ManqueBlanc:=10-PosLastCar;
{Calcul de la taille des blocs standards de blancs à ajouter à la fin de
chaque mot}
TailleBlanc:=trunc(ManqueBlanc / (NbMots-1));
{Construction du bloc standard de blancs à ajouter}
Blanc:=Copy('
',1,TailleBlanc);
{Calcul du nombre de fins de mots devant recevoir un blanc de plus}
BlancSup:=ManqueBlanc-TailleBlanc*(NbMots-1);
End;
End;
Figure A8.15. La procédure Intercalaire
Question 7
Procedure JUSTIFICATION(
Structure : TStruct;
Blanc : string;
BlancSup : integer;
Var Ligne : string;
Var Avance : integer );
(*
Cette procédure réalise dans Ligne la justification spécifiée dans les variables Structure,
Blanc et BlancSup. Le nombre de caractères issus réellement de Texte est mémorisé dans
Avance.
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
101
*)
Var
Wi : integer; {Variables de travail}
WFin : Boolean;
NbMots : integer; {Compte le nombre de mots mis dans ligne (pour test avec
BlancSup}
Begin
{Initialisations}
Wi:=0;
WFin:=False; Ligne:='';
Avance:=0; NbMots:=0;
{Boucle de parcours des cases de Structure}
Repeat
{Test si on a parcouru les 10 cases de Structure}
If Wi>=10 Then Wfin:=True
Else Begin
{Passage à la case suivante de Structure}
Wi:=Wi+1;
{Une case vide ==> on atteint la dernière case remplie de Structure}
If Structure[Wi]='' Then Begin
WFin:=True;
{Poursuite de la construction de la ligne justifiée dans Ligne}
End Else Begin
{Ajout de la case courante de Structure dans Ligne}
Ligne:=Ligne+Structure[wi];
{Mise à jour de Avance : nombre de caractères justifiés issus de
Texte}
Avance:=Avance+Length(Structure[wi]);
{Si le premier caractère est <>blanc alors on a ajouté un mot}
If Copy(Structure[wi],1,1)<>' ' Then Begin
{Mise à jour du compteur de mots justifiés}
NbMots:=NbMots+1;
{Ajout des blancs de justification nécessaires à la fin du mot}
If (length(Ligne)<>10) Then Begin
{Ajout du bloc standard de blancs}
Ligne:=Ligne+Blanc;
{Ajout si nécessaire d'un blanc supplémentaire}
If NbMots<=BlancSup Then Ligne:=Ligne+' ';
End;
End;
End;
End;
Until Wfin;
End;
Figure A8.16. La procédure Justification
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
102
Question 8
Program JUSTIFIER;
(*
Le but de ce programme est de saisir une chaîne de caractères et de l'afficher sous
forme d'une suite de lignes justifiées de longueur 10 de caractères.
*)
Uses Crt, Dos;
Type
TStruct = Array[1..10] of string;
Var
Texte : string; {La chaîne à justifier}
I
: integer; {Variable de parcours de Texte}
Structure : TStruct;
{La liste des 10 prochaîns mots et séquences de blancs
rencontrés à partir de la position I de Texte}
Ligne : string; {La ligne en cours de justification}
NbMots : integer; {Nombre de mots de la ligne en cours de justification}
PosLastCar : integer;
{Position dans la ligne en cours de justification du
dernier
caractère différent de blanc}
Blanc : string; {Séquence de blancs à ajouter à la fin de chaque mot}
BlancSup: integer;{Nombre de fin de mots devant recevoir un blanc de plus}
Avance : integer; {Nombre de caractères de Texte réellement mis dans Ligne}
Wi
: integer; {Variable de travail}
{DEBUT DU PROGRAMME PRINCIPAL}
Begin
{Saisie de la chaîne à justifier}
Write('Entrez votre chaîne de caractères à justifier :'); Readln(Texte);
{Pour faciliter la mise au point : on peut travailler avec une chaîne de test}
If Texte='' Then Begin
Texte:='A AA AAAAAAAAAAA A A AAAAAAA';
Writeln(Texte);
End;
Writeln('Résultat de la justification :');
{Initialisation}
i:=1;
{Boucle de parcours de la chaîne entrée }
While i<Length(Texte) Do Begin
{Isolement dans Structure des 10 prochains mots et blancs
Decompose(Texte ,I ,Structure);
{Calcul préliminaire et élimination de Structure des éléments qui
n'entreront pas dans la prochaîne ligne justifiée}
Pre_Calcul(Structure, NbMots, PosLastCar);
{Calcul des blocs blancs à insérer entre les mots nécessaires à la
justification}
Intercalaire(NbMots, PosLastCar, Blanc, BlancSup);
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
103
{Production dans Ligne d'une ligne justifiée}
Justification(Structure, Blanc, BlancSup, Ligne, Avance);
{Mise à jour de la variable de parcours de Texte}
I:=I+Avance;
{Cas de l'atteinte de la fin du texte : la dernière ligne n'est pas à justifier}
If I>Length(Texte) Then Begin
{On laisse la dernière ligne telle quelle, sans justification}
Ligne:='';
For Wi:=1 to 10 Do Ligne:=Ligne+Structure[wi];
End;
{Sortie de la ligne pour contrôle}
{Les caractère # permettent de rendre compte des blancs de début et fin de
chaîne}
Writeln('#'+Ligne+'#');
End; {Fin du While}
End.
Figure A8.17. Programme principal de test pour la justification
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
104
Annexe 10
Correction des exercices du
chapitre 10
EXERCICE 1
Question 1
Procedure SAUVEGARDER;
{
Cette procédure permet de mémoriser le tableau Damier1 dans le fichier Vie.Txt. A
raison d'une ligne de Damier1 par ligne de Vie.Txt.
}
Var
FVie : TEXT;
Buf_Vie : string;
i, j : integer; {Compteurs de boucles}
Begin
{Ouverture en écriture du fichier Vie.Txt}
Assign(FVie,'VIE.TXT');
Rewrite(Fvie);
{Boucle de parcours des lignes du tableau Damier1}
For i:=1 to 10 Do Begin
Buf_Vie:='';
{Boucle de parcours des colonnes de la ligne courante}
For j:=1 to 10 Do Buf_Vie:=Buf_Vie+Damier1[i, j];
{Ecriture de la ligne sous forme d'une seule chaîne de caractères}
Write(FVie, Buf_Vie);
End;
{Fermeture du fichier}
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
105
Close(FVie);
End;
Figure A10.1. La procédure Sauvegarder
Question 2
Procedure CHARGER;
{
Cette procédure permet d'initialiser le damier, i.e. le tableau Damier1, avec le contenu
du fichier Vie.Txt. A raison d'un enregistrement de Vie.Txt par ligne du tableau
Damier1.
}
Var
FVie : TEXT;
Buf_Vie : string;
i, j : integer; {Compteurs de boucles}
Begin
{Ouverture en lecture du fichier Vie.Txt}
Assign(FVie,'VIE.TXT');
Reset(Fvie);
{Boucle de parcours du fichier Vie.Txt}
For i:=1 to 10 Do Begin
{Lecture de l'enregistrement. courant : une ligne de damier sous forme
de chaîne de caractères}
Readln(FVie, Buf_Vie);
{Parcours de la chaîne lue pour la décomposer en caractères}
For j:=1 to length(Buf_Vie) Do
{Initialisation de Damier1[i,j]}
{:=Buf_Vie[j] et non Copy(Buf_Vie,j,1) car Damier1[i,j] est de type Char}
Damier1[i, j]:= Buf_Vie[j];
End;
{Fermeture du fichier}
Close(FVie);
End;
Figure A10.2. La procédure Charger
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
106
Question 3
Le programme de la figure A10.3. ne reprend pas les deux procédures
Sauvegarder et Charger déjà données aux questions précédentes. Pour obtenir un
programme complet, il faut les y ajouter.
Program VIE;
{
Le but de ce programme est de permettre de jouer au jeux de la vie.
De plus, en fin de partie, le programme mémorisera la configuration obtenue dans le
fichier TEXT de nom Vie.Txt. Corrélativement, en début de programme, le
programme demandera à l'utilisateur s'il veut repartir avec la configuration mémoriseé
dans le fichier Vie.Txt ou au contraire resaisir entièrement une configuration de
départ.
}
Uses
Crt, Dos;
Type
T_Damier = Array[1..10, 1..10] of Char;
Var
Damier1 : T_Damier;
{Le damier principal du jeux}
Damier2 : T_Damier;
{Damier de travail}
Nb_Config : integer;
{Nombre de génération à calculer}
Rep : String;
{Variable de travail}
I : integer;
Procedure MISE_A_BLANC;
{Cette procédure affecte à chaque case de Damier1 le caractère blanc}
Var
Nos_lin, Nos_Col : integer;
Begin
{Mise à blanc de chaque case du damier}
For Nos_Lin:=1 to 10 Do
For Nos_Col:=1 to 10 Do
Damier1[Nos_lin, Nos_Col]:= ' ';
End;
Procedure SAISIE;
{
Cette procédure permet à l'utilisateur de saisir la configuration initiale du damier. Il n'y
a pas de vérification de la validité des données entrées. Elle est sous la responsabilité
de l'utilisateur. Ainsi la saisie d'un caractère non numérique 'fait planter' le programme.
}
Var
Nb_Entree : integer;
Nos_Col : integer; {Nos de colonne de la coordonnée entrée}
Nos_lin : integer; {Nos de ligne de la coordonnée entrée}
Fini : Boolean;
{Variable de travail}
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
107
Begin
{Initialisations pour la saisie}
Nb_Entree:=1;
Fini:=False;
{Boucle permettant de saisir une suite de coordonnées à rendre vivante}
While Not Fini Do Begin
{Affichage de l'état de l'avancement de la saisie}
Gotoxy(1,7); Clreol;
Gotoxy(1,7); Write('Numéro de l''entrée en cours : ',Nb_Entree:2);
Gotoxy(1,8); Write('********************************');
{Saisie du numéro de ligne}
Gotoxy(1,10); ClrEol; {effacement de la ligne de saisie}
Gotoxy(1,10); Write('Entrez le numéro de ligne (O=arrêt) :');
Gotoxy(45,10); ReadLn(Nos_Lin);
{Cas où l'utilisateur exprime le désir d'arrêter la saisie}
If Nos_Lin=0 Then
Fini:=True
Else Begin
{Saisie du numéro de colonne}
Gotoxy(1,11); ClrEol; {effacement de la ligne de saisie}
Gotoxy(1,11); Write('Entrez le numéro de colonne ',Nb_Entree:2,' :');
Gotoxy(45,11); Readln(Nos_Col);
{Affectation de la saisie au damier}
If Damier1[Nos_Lin, Nos_Col]='*' Then
{La cellule était vivante, elle bascule à l'état mort}
Damier1[Nos_Lin, Nos_Col]:=' '
Else
{La cellule était morte, elle bascule à l'état vivant}
Damier1[Nos_Lin, Nos_Col]:='*';
End;
End;
End;
Procedure SORTIR_DAMIER;
{Cette procédure affiche à l'écran le contenu du tableau Damier1}
Var
i, j : integer;
Begin
{Boucle d'affichage écran}
For i:=1 to 10 Do Begin
{Effacement de la ligne à l'écran}
Gotoxy(1,i+13); Clreol;
Gotoxy(1,i+13);
{Affichage de la ligne de Damier1}
For j:=1 to 10 Do
Write(Damier1[i, j])
End;
End;
Procedure CALCUL_NB_VOISINS
(Nos_Lin, Nos_Col: integer; Var Nb_Voisins: integer);
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
108
{
Cette procédure calcule, dans Nb_Voisins, le nombre de voisins vivants de la cellule de
coordonnée Nos_Lin , Nos_Col de Damier1.
}
Var
I, J : integer; {Variables de travail}
Begin
{Calcul du nombre de voisins par inspection du voisinage de Nos_Lin,
Nos_Col}
Nb_Voisins:=0;
{Petit boucle pour balayer à +1 et -1 ligne autour de la ligne Nos_Lin}
For i:= Nos_Lin-1 to Nos_Lin+1 Do
{Petit boucle pour balayer à +1 et -1 col. autour de la colonne Nos_Col}
For j:=Nos_Col-1 to Nos_Col+1 Do
{Test si on est encore dans le damier : problème des bords du damier}
If (1<=i) and (i<=10) and (1<=j) and (j<=10) Then
{Test si la cellule est vivante}
If Damier1[i, j]='*' Then
Nb_Voisins:=Nb_Voisins+1;
{Rectification éventuelle du calcul}
{En effet, il faut compter le nombre de voisins, la cellule centrale a peut-être été
comptée dans Nb_Voisins si elle était vivante, il faut alors la soustraire de
Nb_Voisins}
if Damier1[Nos_lin, Nos_Col]='*' Then
Nb_Voisins:=Nb_Voisins-1;
End;
Procedure DAMIER_SUIVANT;
{
Cette procédure calcule le damier de la génération suivante. Pour cela elle calcule la
génération suivante dans le damier de travail Damier2. Puis recopie le résultat dans le
damier principal Damier1
}
Var i, j : integer; {Variable de travail}
Nb_Voisins : integer;
Begin
{Boucle de parcours des lignes de Damier1}
For i:=1 to 10 Do Begin
{Boucle de parcours des colonnes de Damier1}
For j:=1 to 10 Do Begin
{Calcul du nombre de voisins vivants de la case courante}
Calcul_Nb_Voisins(I, J, Nb_Voisins);
{Mise à jour de la case de la génération suivante dans Damier2}
If (Nb_Voisins=2) or (Nb_Voisins=3) Then
Damier2[i, j]:='*'
Else
Damier2[i, j]:=' ';
End;
End;
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
109
{Transfert du damier de travail, Damier2, dans le damier principal,
Damier1}
For i:=1 to 10 Do
For j:=1 to 10 Do
Damier1[i, j]:=Damier2[i, j];
End;
{DEBUT DU PROGRAMME PRINCIPAL}
Begin
{Annonce du programme}
ClrScr;
gotoxy(25,1); Write('JEUX DE LA VIE');
gotoxy(25,2); Write('**************');
{Demande s'il faut reprendre une ancienne configuration}
Gotoxy(1,5); Write('Voulez-vous repartir avec la dernière configuration',
' enregistrée (O-N):');
Readln(Rep);
{Cas où l'utilisateur veut repartir avec l'ancienne configuration}
If (Rep='O') or (Rep='o') then
{Chargement dans Damier1 avec le contenu du fichier Vie.Txt}
Charger
{Cas où l'utilisateur veut repartir avec un damier vierge}
Else
{Initialisation à blanc des cases de Damier1}
Mise_A_Blanc;
{Modification ou saisie du damier par l'utilisateur}
Saisie;
{Affichage du damier pour vérification}
Sortir_Damier;
Gotoxy(1,24); Write('Génération 1');
{Demande du nombre de générations à générer}
Gotoxy(1,13); Write('Nombre de configurations à générer :');
Readln(Nb_Config);
{Calcul des générations demandées}
{i:=2 car la première génération est celle donnée par l'utilisateur}
For i:= 2 to Nb_Config Do begin
{Calcul proprement dite dans Damier1 de la génération suivante}
Damier_Suivant;
{Affichage du damier calculé}
Sortir_Damier;
{Temporisation pour permettre à l'utilisateur de voir l'affichage }
Gotoxy(1,24);
Write('Génération ',I:3,'. Appuyez sur une touche pour continuer');
Readln(Rep)
End; {Fin du For}
{Mémorisation dans le fichier Vie.Txt de la dernière configuration obtenue}
Sauvegarder;
End.
Figure A10.3. Le jeux de la vie et fichiers
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
110
EXERCICE 2
Program AnglaisFrancais;
{
Programmation du codage d'une phrase de l'anglais en français en utilisant un
fichier à accès direct pour mémoriser le dictionnaire.
}
Uses
Dos, Crt;
Type
TDico = record
Mot_anglais : string;
Mot_Francais : string;
end;
Var
FDico : file of TDico;
Buf_Dico : TDico;
ChAng, ChFra : string; {La phrase originale anglaise et sa traduction
française}
Pos : integer;
{La position courante dans ChAng}
Mot, Mot_Traduit : string; {Variable de travail}
Rep : string;
{Variable de travail}
Procedure RECHERCHE(Mot : string; Var Nos_Case : integer);
{
Cette procédure parcours le fichier FDico à la recherche du mot Mot. Si la
recherche réussie Nos_Case renvoie le numéro d'enregistrement dans lequel Mot a
été trouvé sinon elle renvoie FileSize(FDico)
z
Var Fini, Trouve : string;
Begin
{Initialisations}
Nos_Case:=0;
Fini:='FAUX';
Trouve:='FAUX';
{Boucle de parcours du fichier FDico à la recherche de Mot}
While (Fini='FAUX') and (Trouve='FAUX') Do Begin
{Cas où la fin du fichier est atteinte}
If Nos_Case>=FileSize(FDico) Then
Fini:='VRAI'
Else begin
{Lecture de l'enregistrement suivant}
seek(FDico, Nos_Case);
Read(FDico, Buf_Dico);
{Test s'il s'agit du mot recherché}
If Buf_Dico.Mot_Anglais=Mot Then
Trouve:='VRAI'
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
111
Else
{Passage à l'enregistrement suivant}
Nos_Case:=Nos_Case+1;
end;
End; {Fin du while}
End;
Procedure AJOUTER(Mot : string; Var Mot_Traduit : string);
{
Demande de la traduction française du mot anglais Mot et méorisation de celle-ci
dans Mot_Traduit. Le couple Mot et Mot_Traduit est ajoutée en fin de
dictionnaire}
Begin
{Demande à l'utilisateur de la traduction française du mot anglais Mot}
Writeln('Traduction de ', Mot, ' inconnue, merci de la donner :');
Readln(Mot_Traduit);
{Cas où le dictionnaire est considéré comme plein}
If FileSize(FDico)>=100 Then
Writeln('Dictionnaire plein : traduction non mémorisée !')
{Cas où il reste de la place dans le dictionnaire}
Else Begin
{Ajout du mot anglais et de sa tradution française dans le dictionnaire}
Buf_Dico.Mot_Anglais:=Mot;
Buf_Dico.Mot_Francais:=Mot_Traduit;
Seek(FDico, Filesize(FDico));
Write(FDico, Buf_Dico);
End;
End;
Procedure TRADUCTION(Mot : string; Var Mot_Traduit : string);
Var Nos_Case : integer;
Begin
{Recherche dans le dictionnaire de la traduction du mot français Mot}
Recherche(Mot, Nos_Case);
{Cas où le mot n'est pas présent dans le dictionnaire}
If Nos_Case=Filesize(Fdico) Then
{Demande à l'utilisateur de sa traduction et ajout dans le dictionnaire}
Ajouter(Mot, Mot_Traduit)
Else
{Mémorisation de sa traduction dans Mot_Traduit}
Mot_Traduit:=buf_dico.Mot_francais;
End;
Procedure MOT_SUIVANT(Ch : string; Var Mot : string; Var Pos : integer);
{Recherche à partir de la position Pos de Ch et mise dans Mot du mot suivant}
Var Car : string;
Fini, Trouve : string;
Begin
{Initialisations pour la prochaîne boucle}
Fini:='FAUX';
Trouve:='FAUX';
{Parcours de la chaîne tant que l'on rencontre des blancs}
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
112
While (Fini='FAUX') and (Trouve='FAUX') Do Begin
{Cas où l'on a atteint la fin de la chaîne}
If Pos>Length(Ch) Then
Fini:='VRAI'
Else Begin
{Isolement du caractère courant}
Car:=Copy(Ch, Pos, 1);
{Le caractère courant est un blanc : fin de la boucle}
If Car<>' ' Then
Trouve:='VRAI'
Else
{Passage au caractère suivant}
Pos:=Pos+1;
End;
End; {Fin du While}
{Initialisations pour la deuxième boucle}
Mot:='';
Trouve:='FAUX';
{Parcours tant que l'on rencontre des caractères différents du blanc}
While (Fini='FAUX') and (Trouve='FAUX') Do Begin
{Cas où l'on atteint la fin de la chaîne}
If Pos>Length(Ch) Then
Fini:='VRAI'
Else Begin
{Isolement du caractère courant}
Car:=Copy(Ch, Pos, 1);
{Cas où l'on rencontre un blanc : c'est la fin du mot}
If Car=' ' Then
Trouve:='VRAI'
Else Begin {donc <> ' '}
{Accumulation du caractère courant dans la variable Mot}
Mot:=Mot+Car;
{Passage au caractère suivant}
Pos:=Pos+1;
End;
End;
End; ; {Fin du While}
End;
{DEBUT DU PROGRAMME PRINCIPAL}
Begin
{Demande à l'utilisateur s'il veut reprendre l'ancien dictionnaire Dico.Don}
Clrscr;
Gotoxy(1,5); Write('Reprise du dictionnaire (O-N) :');
Readln(Rep);
Rep[1]:=UpCase(Rep[1]);
Assign(FDico,'Dico.don');
{Cas où l'utilisateur veut repartir avec un dictionnaire vierge}
If Rep='N' Then
{Ouverture en écriture donc remise à zéro de FDico}
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
113
Rewrite(Fdico)
Else
{Ouverture normal, sans remise à zéro, de FDico}
Reset(Fdico);
{Entrée de la phrase anglaise à traduire}
Writeln('Entrez la phrase anglaise à traduire :');
Readln(ChAng);
{Initialisations}
Pos:=1; {on commence le parcours au premier caractère de ChAng}
ChFra:='';
{Boucle de parcours de la phrase anglaise pour traduction}
While Pos<=Length(ChAng) Do Begin
{Isolement du mot suivant de la phrase anglaise}
Mot_Suivant(ChAng, Mot, Pos);
{Cas où un mot a été répéré}
If Mot<>'' Then Begin
{Traduction du mot repéré soit par demande à l'utilisateur soit
directement grâce au dictionnaire}
Traduction(Mot, Mot_Traduit);
{Ajout du mot traduit à la phrase réponse en français}
ChFra:=ChFra+Mot_Traduit+' ';
End;
End; {Fin du While}
{Sortie du résultat}
Writeln('On obtient la traduction : ', ChFra);
End.
Figure A10.4. Codage anglais-français et fichiers à accès direct
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
114
Annexe 11
Programmation du projet KWIC
Cette annexe présente la traduction Turbo Pascal des algorithmes étudiés au
chapitre 11. Il s'agit de la programmation du mini-projet d'informatique
documentaire qui consiste à mettre en place un KWIC (Key Word In Context).
Tous les programmes sont donnés dans leur intégralité. CepEndant afin d'éviter du
remplissage, les différents programmes de tri et de fusion, qui sont quasiment
identiques les uns des autres, n'ont été donné qu'en un seul exemplaire. Le lecteur
pourra facilement par un "couper-coller' de l'exemplaire donné et une légère
adaptation, les programmer.
A11.1 LE PROGRAMME D'INITIALISATION
Le but principal de notre projet KWIC est d'imprimer chaque mois trois
catalogues : identification, auteur et mot-clef. Pour cela, ces catalogues sont tenus à
jour sous forme de fichiers séquentiels à raison d'un fichier par catalogue. De plus
un historique des fichiers est conservé, les fichiers de départ ont leurs noms terminé
par 000, les fichiers après le premier mois ont leurs noms terminé par 001, les
fichiers après le second mois ont leurs noms terminé par 002, .... Le premier
traitement à réaliser, et à ne faire qu'une seule fois, est celui de la création des trois
fichiers de départ : Ide_000, Aut_000 et Mot_000. Ces trois vides seront vides
d'enregistrements, aucun document n'ayant été encore recensés.
Programme d'initialisation du projet KWIC
***********************************
Voulez-vous continuer (O=Oui) :
Figure A11.1. Ecran d'accueil du programme INITIALISATION
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
115
Le programme Initialisation de la figure A11.2 réalise ce traitement. Il créé ces
trois fichiers vides Ide_000, Aut_000 et Mot_000 dans la directory C:\Bruno\Kwic.
Attention cette directory doit exister au préalable du lancement du programme. La
figure A11.1 présente l'écran d'accueil qui s'affiche au lancement de ce programme.
Program INITIALISATION;
{
Le but de ce programme est de créer les fichiers de départ nécessaires au projet KWIC
}
Uses
Dos, Crt;
Type
TIden = record
Ref : string[10];
Auteurs : string[110];
Titre : string[120];
End;
TAuteur = record
Auteur : string[20];
Ref : string[10];
Titre : string[120];
End;
TMot = record
Ref : string[10];
Cadre : string[120];
End;
Var
FIden : file of TIden;
FAuteur : file of TAuteur;
FMot : file of TMot;
FEntDon : file of TIden;
Rep : string[1];
Begin
{Annonce du programme à l'utilisateur}
ClrScr;
WriteLn('Programme d''initialisation du projet KWIC');
WriteLn('******************************************');
WriteLn;
Write('Voulez-vous continuer (O=Oui) :');
ReadLn(Rep);
If Rep='o' Then Rep:='O';
{Cas de l'abandon par l'utilisateur}
If Rep <> 'O' Then WriteLn('Initialisation non faite !')
Else Begin
{Création du catalogue des identifications}
Assign(FIden,'C:\BRUNO\KWIC\IDE_000');
Rewrite(FIden);
{Création du catalogue des auteurs}
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
116
Assign(FAuteur,'C:\BRUNO\KWIC\AUT_000');
Rewrite(FAuteur);
{Création du catalogue des mots-clefs}
Assign(FMot,'C:\BRUNO\KWIC\MOT_000');
Rewrite(FMot);
{Création du fichier des documents du mois}
Assign(FEntDon,'C:\BRUNO\KWIC\ENTDON');
Rewrite(FEntDon);
{Fermeture des fichiers}
Close(FIden); Close(FAuteur); Close(FMot); Close(FEntDon);
WriteLn('Initialisation terminée !');
End;
End.
Figure A11.2. Le programme Initialisation
A11.2. LE PROGRAMME DE SAISIE DES REFERENCES
Les références des nouveaux documents recensés par le documentaliste sont
saisis dans un fichier d'attente, puis chaque fin mois intégré dans la base du KWIC.
Gestion du fichier des documents du mois courant
****************************************
Opération demandée :
A=Ajouter
M=Modifier
S=Supprimer
P=Premier document
D=Dernier document
V=suiVant
R=pRécédent
F=Fin
Figure A11.3. Ecran d'accueil du programme Saisie
Le programme Saisie de la figure A11.4 permet cette saisie dans le fichier à
accès direct EntDon de la directory C:\Bruno\Kwic. Il permet non seulement l'ajout
de nouvelles références de documents dans le fichier EntDon, mais également leurs
modifications ou leurs suppressions. Le fichier EntDon doit exister au préalable du
lancement du programme. La figure A11.3 présente l'écran d'accueil qui s'affiche au
lancement de ce programme.
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
117
Program SAISIE;
{
Le but de ce programme est de permettre à l'utilisateur de gérer le fichier EntDon
}
Uses
Dos, Crt;
Type
TIden = record
Ref : string[10];
Auteurs : string[110];
Titre : string[120];
End;
Var
FEntDon : file of TIden;
Enr_EntDon : TIden;
Operation : string;
Nos_EnrCour : integer;
Procedure AJOUTER; {Ajout d'un nouvel enregistrement en fin de fichier}
Begin
{Affichage de la grille de saisie et saisie des données document}
ClrScr;
WriteLn('Ajout d''un nouvel enregistrement');
WriteLn('**********************************');
WriteLn;
Gotoxy(1,5); Write('Entrer une identification :'); ReadLn(Enr_EntDon.Ref);
Gotoxy(1,6); Write('Entrer les auteurs
:'); ReadLn(Enr_EntDon.Auteurs);
Gotoxy(1,7); Write('Entrer une titre
:'); ReadLn(Enr_EntDon.Titre);
{Ajout des données document en fin de fichier}
Seek(FEntDon,filesize(FEntDon));
Write(FEntDon, Enr_EntDon);
{Mise à jour du numéro du dernier l'enregistrement utilisé : enr. courant}
Nos_EnrCour:=filesize(FEntDon)-1;
End;
Procedure MODIFIER;
{Modification d'un enregistrement déjà existant}
Var Nos_Enr : integer;
Enr2_EntDon : TIden; {buffer de saisie}
Rep : string;
Begin
{Affichage informatif indiquant le type d'opération en cours }
ClrScr;
WriteLn('Modification d''un ancien enregistrement');
WriteLn('*****************************************');
WriteLn;
{Saisie du numéro d'enregistrement à modifier}
Gotoxy(1,5); Write('Entrer le numéro d''enregistrement :'); ReadLn(Nos_Enr);
{Cas où le numéro saisi ne correspond pas à un enregistrement existant}
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
118
if (Nos_Enr<0) or (Nos_Enr>=filesize(FEntDon)) Then Begin
Gotoxy(1,7); WriteLn('Enregistrement inexistant !');
Gotoxy(1,14); Write('Appuyez sur une touche pour continuer'); ReadLn(Rep);
End else Begin
{Lecture de l'enregistrement demandé}
Seek(FEntDon, Nos_Enr);
Read(FEntDon, Enr_EntDon);
{Saisie des nouvelles données sur l'identification}
Gotoxy(1,7); Write('Ancienne identification='+Enr_EntDon.Ref);
Gotoxy(40,7); Write('Nouvelle =');
ReadLn(Enr2_EntDon.Ref);
If Enr2_EntDon.Ref<>'' Then {entrée vide ==> pas de changement}
Enr_EntDon.Ref:=Enr2_EntDon.Ref;
{Saisie des nouvelles données sur les auteurs}
Gotoxy(1,8); Write('Anciens Auteurs='+Enr_EntDon.Auteurs);
Gotoxy(40,8); Write('Nouveaux =');
ReadLn(Enr2_EntDon.Auteurs);
If Enr2_EntDon.Auteurs<>'' Then {entrée vide ==> pas de changement}
Enr_EntDon.Auteurs:=Enr2_EntDon.Auteurs;
{Saisie des nouvelles données sur le titre}
Gotoxy(1,10); Write('Ancien titre='+Enr_EntDon.Titre);
Gotoxy(40,10);Write('Nouveau =');
ReadLn(Enr2_EntDon.Titre);
If Enr2_EntDon.Titre<>'' Then {entrée vide ==> pas de changement}
Enr_EntDon.Titre:=Enr2_EntDon.Titre;
{Réécriture de l'enregistrement}
Seek(FEntDon, Nos_Enr);
Write(FEntDon, Enr_EntDon);
{Mise à jour du numéro du dernier l'enregistrement utilisé : enr. courant}
Nos_EnrCour:=Nos_Enr;
End;
End;
Procedure SUPPRIMER;
{Suppression d'un enregistrement déjà
existant}
Var Rep : string;
Nos_Enr : integer;
Begin
{Affichage informatif indiquant le type d'opération en cours }
ClrScr;
WriteLn('Suppression logique d''un enregistrement');
WriteLn('*****************************************');
WriteLn;
{Saisie du numéro d'enregistrement à supprimer}
Gotoxy(1,5); Write('Entrer le numéro d''enregistrement à supprimer :');
ReadLn(Nos_Enr);
{Cas où le numéro saisi ne correspond pas à un enregistrement existant}
if (Nos_Enr<0) or (Nos_Enr>=filesize(FEntDon)) Then Begin
Gotoxy(1,7); WriteLn('Enregistrement inexistant !');
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
119
Gotoxy(1,14); Write('Appuyez sur une touche pour continuer'); ReadLn(Rep);
End else Begin
{Lecture pour contrôle avant suppression de l'enr. à supprimer}
Seek(FEntDon, Nos_Enr);
Read(FEntDon, Enr_EntDon);
{Affichage pour demande de confirmation de la suppression}
Gotoxy(1,7); Write('Ancienne identification='+Enr_EntDon.Ref);
Gotoxy(1,8); Write('Anciens Auteurs='+Enr_EntDon.Auteurs);
Gotoxy(1,10); Write('Ancien titre='+Enr_EntDon.Titre);
Gotoxy(1,13); Write('Confirmez-vous la suppression -logique- (O=Oui) :');
ReadLn(Rep);
{L'utilisation a confirmé la suppression}
If Rep='O' Then Begin
{Suppression logique de l'enregistrement}
Enr_EntDon.Ref:='**********';
Seek(FEntDon, Nos_Enr);
Write(FEntDon, Enr_EntDon);
End;
{Mise à jour du numéro du dernier l'enregistrement utilisé : enr. courant}
Nos_EnrCour:=Nos_Enr;
End;
End;
Procedure POS_PREMIER;
{Affichage du premier enregistrement}
Var Rep : string;
Begin
{Affichage informatif indiquant le type d'opération en cours }
ClrScr;
WriteLn('Positionnement sur le premier enregistrement');
WriteLn('********************************************');
WriteLn;
{Cas où le fichier est vide}
If FileSize(FEntDon)<1 Then
Write('Fichier vide, positionnement sur premier enregistrement impossible !')
Else Begin
{Lecture du premier enregistrement, i.e. l'enregistrement numéroté 0}
Seek(FEntDon, 0);
Read(FEntDon, Enr_EntDon);
{Affichage de l'enregistrement proprement dit }
Gotoxy(1,7); Write('Identification='+Enr_EntDon.Ref);
Gotoxy(1,9); Write('Auteurs='+Enr_EntDon.Auteurs);
Gotoxy(1,11); Write('Titre='+Enr_EntDon.Titre);
{Mise à jour du numéro du dernier l'enregistrement utilisé : enr. courant}
Nos_EnrCour:=0;
End;
Gotoxy(1,14); Write('Appuyez sur une touche pour continuer'); ReadLn(Rep);
End;
Procedure POS_DERNIER; ;
{Affichage du dernier enregistrement}
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
120
Var Rep : string;
Begin
{Affichage informatif indiquant le type d'opération en cours }
ClrScr;
WriteLn('Positionnement sur le dernier enregistrement');
WriteLn('********************************************');
WriteLn;
{Cas où le fichier est vide}
If FileSize(FEntDon)<1 Then
Write('Fichier vide, positionnement sur dernier enregistrement impossible !')
Else Begin
{Lecture du dernier enregistrement}
Seek(FEntDon, filesize(FEntDon)-1);
Read(FEntDon, Enr_EntDon);
{Affichage de l'enregistrement proprement dit }
Gotoxy(1,7); Write('Identification='+Enr_EntDon.Ref);
Gotoxy(1,9); Write('Auteurs='+Enr_EntDon.Auteurs);
Gotoxy(1,11); Write('Titre='+Enr_EntDon.Titre);
{Mise à jour du numéro du dernier l'enregistrement utilisé : enr. courant}
Nos_EnrCour:=filesize(FEntDon)-1;
End;
Gotoxy(1,14); Write('Appuyez sur une touche pour continuer'); ReadLn(Rep);
End;
Procedure SUIVANT;
{Affichage de l'enregistrement suivant}
Var Rep : string;
Begin
{Affichage informatif indiquant le type d'opération en cours }
ClrScr;
WriteLn('Positionnement sur l''enregistrement suivant');
WriteLn('*********************************************');
WriteLn;
{Cas où le fichier est vide}
If FileSize(FEntDon)<1 Then
Write('Fichier vide, positionnement sur l''enregistrement suivant impossible !')
{Cas où l'enregistrement courant est le dernier enregistrement}
Else If Nos_EnrCour=filesize(FEntDon)-1 Then
Write('Vous êtes déjà sur le dernier enregistrement !')
Else Begin
{Incrémentation du numéro de l'enregistrement courant}
Nos_EnrCour:=Nos_EnrCour+1;
{Lecture de l'enregistrement}
Seek(FEntDon, Nos_EnrCour);
Read(FEntDon, Enr_EntDon);
{Affichage de l'enregistrement lu}
Gotoxy(1,4); Write('Enregistrement numéro :',Nos_EnrCour:5);
Gotoxy(1,7); Write('Identification='+Enr_EntDon.Ref);
Gotoxy(1,9); Write('Auteurs='+Enr_EntDon.Auteurs);
Gotoxy(1,11); Write('Titre='+Enr_EntDon.Titre);
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
121
End;
Gotoxy(1,14); Write('Appuyez sur une touche pour continuer'); ReadLn(Rep);
End;
Procedure PRECEDENT;
{Affichage de l'enregistrement suivant}
Var Rep : string;
Begin
{Affichage informatif indiquant le type d'opération en cours }
ClrScr;
WriteLn('Positionnement sur l''enregistrement précédent');
WriteLn('***********************************************');
WriteLn;
{Cas où le fichier est vide}
If FileSize(FEntDon)<1 Then
Write('Fichier vide, positionnement sur l''enregistrement précédent impossible !')
{Cas où l'enregistrement courant est le premier enregistrement du fichier}
Else If Nos_EnrCour=0 Then
Write('Vous êtes déjà sur le premier enregistrement !')
Else Begin
{Dérémentation du numéro de l'enregistrement courant}
Nos_EnrCour:=Nos_EnrCour-1;
{Lecture de l'enregistrement}
Seek(FEntDon, Nos_EnrCour);
Read(FEntDon, Enr_EntDon);
{Affichage de l'enregistrement lu}
Gotoxy(1,4); Write('Enregistrement numéro :',Nos_EnrCour:5);
Gotoxy(1,7); Write('Identification='+Enr_EntDon.Ref);
Gotoxy(1,9); Write('Auteurs='+Enr_EntDon.Auteurs);
Gotoxy(1,11); Write('Titre='+Enr_EntDon.Titre);
End;
Gotoxy(1,14); Write('Appuyez sur une touche pour continuer'); ReadLn(Rep);
End;
{DEBUT DU PROGRAMME PRINCIPAL}
Begin
{Ouverture du fichier EntDon}
Assign(FEntDon,'C:\bruno\kwic\EntDon');
Reset(FEntDon);
{Initialisations}
Operation:=' ';
Nos_EnrCour:=0;
{Boucle générale de saisie des ordres de l'utilisateur}
While Operation<>'F' Do Begin
{Affichage des choix possibles}
ClrScr;
WriteLn('Gestion du fichier des documents du mois courant ');
WriteLn('*************************************************');
WriteLn;
Gotoxy(1,5); WriteLn('Opération demandée :');
Gotoxy(1,6); WriteLn(' A=Ajouter');
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
122
Gotoxy(1,7); WriteLn(' M=Modifier');
Gotoxy(1,8); WriteLn(' S=Supprimer');
Gotoxy(1,9); WriteLn(' P=Premier document');
Gotoxy(1,10);WriteLn(' D=Dernier document');
Gotoxy(1,11);WriteLn(' V=suiVant');
Gotoxy(1,12);WriteLn(' R=pRécédent');
Gotoxy(1,13);WriteLn(' F=Fin');
Gotoxy(1,15);WriteLn('Enregistrement en cours :',Nos_EnrCour:4);
Gotoxy(1,16);WriteLn('Dernier numéro d''enregistrement du fichier :',
(FileSize(FEntDon)-1):4);
{Saisie du choix de l'utilisateur}
Gotoxy(22,5);ReadLn(Operation);
{Lancement de la procédure adéquate}
Operation[1]:=Upcase(Operation[1]); {mise en majuscule}
Case Operation[1] of
'A' : Ajouter;
'M' : Modifier;
'S' : Supprimer;
'P' : pos_Premier;
'D' : pos_Dernier;
'V' : suiVant;
'R' : pRecedent;
End;
End;
{Fermeture du fichier}
Close(FEntDon);
End.
Figure A11.4. Le programme Saisie
A11.3. LE PROGRAMME D'ECLATEMENT
La phase d'intégration, dans la base du KWIC, des références des documents
saisis durant le mois commence par l'éclatement du fichier EntDon en trois
fichiers : F_Iden, F_Aut et F_Mot.
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
123
Eclatement du fichier des documents du mois courant
*******************************************
Voulez-vous continuer (O=Oui) :
Figure A11.5. Ecran d'accueil du programme Eclat
Le programme Eclat de la figure A11.6 réalise ce traitement. Il crée trois
fichiers F_Iden, F_Aut et F_Mot dans la directory C:\Bruno\Kwic. Puis parcourt le
fichier EntDon de la directory C:\Bruno\Kwic et crée pour chaque enregistrement
du fichier EntDon un enregistrement dans le fichier F_Iden, un enregistrement par
auteur dans le fichier F_Aut et un enregistrement par mot-clef dans le fichier
F_Mot. Les enregistrements dont le champ Ref est égale à '**********' sont
ignorés car considérés comme supprimer logiquement. La figure A11.5 présente
l'écran d'accueil qui s'affiche au lancement de ce programme.
Program ECLAT;
{
Le but de ce programme est de réaliser l'éclatement du fichier EntDon du projet
KWIC en trois fichiers : F_Ide, F_Aut et F_Mot
}
Uses
Dos, Crt;
Const {80 blancs}
Blanc='
';
Type
TIden = record
Ref : string[10];
Auteurs : string[110];
Titre : string[120];
End;
TAuteur = record
Auteur : string[20];
Ref : string[10];
Titre : string[120];
End;
TMot = record
Ref : string[10];
Cadre : string[120];
End;
Var
FEntDon : file of TIden;
FIden : file of TIden;
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
124
Enr_EntDon : TIden;
FAuteur : file of TAuteur;
Enr_Faut : TAuteur;
fmot : file of tmot;
Enr_FMot : tmot;
Nos_EnrCour : integer;
Rep : string;
Procedure RAZ_FICHIERS;
{Remise à zéro des fichiers catalogues mensuels non triés : F_Iden, F_Aut et F_Mot}
Begin
Assign(FIden,'C:\BRUNO\KWIC\F_Iden');
Rewrite(FIden);
Assign(FAuteur,'C:\BRUNO\KWIC\F_Aut');
Rewrite(FAuteur);
Assign(fmot,'C:\BRUNO\kwic\F_Mot');
Rewrite(fmot);
End;
Procedure AJOUT_F_IDE;
{Eclatement d'un enregistrement dans F_Ide = simple copie de l'enregistrement}
Begin
Write(FIden, Enr_EntDon);
End;
Procedure AJOUT_F_AUT;
{Eclatement de l'enregistrement dans F_Aut}
Var
Pos : integer;
Wauteur, car : string;
Trouve : boolean;
Begin
{Initialisations du compteur de parcours de la liste des auteurs}
Pos:=0;
{Boucle de parcours pour isoler les différents auteurs de la liste des auteurs}
While Pos<length(Enr_EntDon.Auteurs) Do Begin
{Initialisations}
Wauteur:='';
Trouve:=False;
{Boucle qui isole un auteur}
While (not trouve) and (pos<length(Enr_EntDon.Auteurs)) Do Begin
{Passage au caractère suivant}
Pos:=Pos+1;
{Sélection du caractère courant}
Car:=copy(Enr_EntDon.Auteurs, pos, 1);
{Détection de la virgule ==> fin du nom d'un auteur}
If Car=',' Then Trouve:=True
Else Wauteur:=Wauteur+Car;
End;
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
125
{Troncature à 20 caractères de l'auteur isolé}
If length(wauteur)>20 Then wauteur:=copy(wauteur,1,20);
{Ajout d'un enregistrement de F_Aut correspondant à l'auteur isolé}
Enr_Faut.Auteur:=WAuteur;
Enr_Faut.Ref:=Enr_EntDon.Ref;
Enr_Faut.Titre:=Enr_EntDon.Titre;
Write(FAuteur, Enr_Faut);
End;
End;
Procedure AJOUT_F_MOT;
{Eclatement de l'enregistrement dans F_Aut}
Var
Pos : integer;
Wmot, WTitre, car : string;
Trouve : boolean;
Debut_analyse : integer;
Begin
{Initialisations du compteur de parcours du titre}
Pos:=0;
{Boucle pour isoler les différents mots-clefs du titre}
While Pos<length(Enr_EntDon.Titre) Do Begin
{Initialisations}
Wmot:='';
Trouve:=False;
{Pour mémoriser le début du futur mot repéré}
Debut_analyse:=Pos+1;
{Boucle qui isole un mot-clef}
While (not trouve) and (pos<length(Enr_EntDon.Titre)) Do Begin
{Passage au caractère suivant}
Pos:=Pos+1;
{Isolement du caractère courant}
Car:=copy(Enr_EntDon.Titre, pos, 1);
{Rencontre d'un caractère blanc ==> fin d'un mot}
If Car=' ' Then Trouve:=True
Else Wmot:=Wmot+Car;
End;
{On élimine les mots de moins de trois lettres}
If length(wmot)>3 Then Begin
Enr_FMot.Ref:=Enr_EntDon.Ref;
{Cadrage du titre en fonction du mot repéré}
WTitre:=copy(Blanc,1,60-Debut_Analyse)+Enr_EntDon.Titre;
If Length(wTitre)>120 Then WTitre:=copy(wTitre,1,120);
Enr_FMot.cadre:=wTitre;
{Ajout de l'enregistrement dans F_Mot}
Write(fmot, Enr_FMot);
End;
End;
End;
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
126
{DEBUT DU PROGRAMME PRINCIPAL}
Begin
{Annonce du programme à l'utilisateur}
ClrScr;
Gotoxy(10,1); Write('Eclatement du fichier des documents du mois courant');
Gotoxy(10,2); Write('***************************************************');
WriteLn;
Write('Voulez-vous continuer (O=Oui) :');
ReadLn(Rep);
If Rep='o' Then Rep:='O';
If Rep <> 'O' Then WriteLn('Eclatement non fait !')
Else Begin
{Remise à zéro des fichiers catalogues du mois :
F_Iden, F_Aut et F_Mot}
Raz_Fichiers;
{Ouverture du ficher EntDon}
Assign(FEntDon,'C:\Bruno\Kwic\EntDon');
Reset(FEntDon);
{Boucle de parcours du fichier EntDon}
While not eof(FEntDon) Do Begin
{Incrémentation du numéro d'enregistrement courant}
Nos_EnrCour:=Nos_EnrCour+1;
{Lecture de l'enregistrement courant}
Read(FEntDon, Enr_EntDon);
{Cas où l'enregistrement n'est pas logiquement supprimé}
If Enr_EntDon.Ref<>'**********' Then Begin
{Eclatement de l'enregistrement dans F_Ide}
Ajout_F_Ide;
{Eclatement de l'enregistrement dans F_Aut}
Ajout_F_Aut;
{Eclatement de l'enregistrement dans F_Mot}
Ajout_F_Mot;
End;
End;
{Fermeture des fichiers}
Close(FEntDon); Close(FIden); Close(FAuteur); Close(fmot);
WriteLn('Eclatement terminé !')
End;
End.
Figure A11.6. Le programme Eclat
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
127
A11.4. LES PROGRAMMES DE TRI
La deuxième étape de la phase d'intégration est le tri des trois fichiers : F_Iden,
F_Aut et F_Mot créés par le programme Eclat pour obtenir les fichiers triés
Mj_Ide, Mj_Aut et Mj_Mot.
KWIC : programme de tri du catalogue des identifications du mois
*****************************************************
Voulez-vous continuer (O=Oui) : O
Début du chargement du fichier en mémoire centrale
53
Début du tri
53
Début de la recopie du tri
53
Tri terminé !
Figure A11.7. Ecran du programme Triden en fin d'exécution
Le programme Triden de la figure A11.8 réalise ce traitement pour le fichier
F_Iden. Nous laissons le soin au lecteur de le 'couper-coller' et de l'adapter pour
obtenir les programmes qui permettront le tri des deux autres fichiers : F_Aut et
F_Mot. L'algorithme utilisé pour réaliser ce tri est le plus simple qu'il soit et a été
étudié au chapitre 11. La figure A11.6 présente l'état de l'écran en fin de tri.
Program TRIDEN;
{
Le but de ce programme est de trier le catalogue des identifications du mois. F_Ide
non trié donnera Mj_Ide trié.
La technique de tri utilisé est la plus simple qui soit : chargement en mémoire centrale
dans un vecteur; tri par sélection-permutation du vecteur puis écriture vecteur trié
dans le fichier Mj_Ide.
}
Uses
Dos, Crt;
Type
TIden = record
Ref : string[10];
Auteurs : string[110];
Titre : string[120];
End;
TTab_Tri = record
Travail : array[1..100] of TIden; {Limité à cent documents}
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
128
Limit : integer; {nombre de cases occupées dans travail}
End;
Var
Tab_Tri : TTab_Tri; {variable globale}
Rep : string;
Procedure CHARGER;
{ Cette procédure charge le fichier à trier dans Tab_Tri}
Var
FIden : file of TIden;
Begin
{Affichage informatif à destination de l'utilisateur}
Gotoxy(1,5); WriteLn('Début du chargement du fichier en mémoire centrale.');
{Ouoverture du fichier}
Assign(FIden, 'C:\Bruno\Kwic\F_Iden');
Reset(FIden); {On suppose le fichier exister}
{Initialisation}
Tab_Tri.Limit:=0;
{Parcours du fichier du début jusqu'à la fin}
While not eof(FIden) do Begin
Tab_Tri.Limit:=Tab_Tri.Limit+1;
Gotoxy(1,6); WriteLn(Tab_Tri.Limit:3);
{Lecture du fichier et remplissage de Tab_Tri}
Read(FIden, Tab_Tri.travail[Tab_Tri.Limit]);
End;
{Fermeture du fichier}
Close(FIden);
End;
Procedure TRIER;
{Cette procédure tri le vecteur Tab_Tri}
Var i, j : integer;
Temp : TIden;
Begin
{Affichage informatif à destination de l'utilisateur}
Gotoxy(1,7); WriteLn('Début du tri.');
{Boucle externe du tri par sélection-permutation}
For i:=1 to Tab_Tri.Limit-1 do Begin
{Informer l'utilisateur de la progression du tri}
Gotoxy(1,8); WriteLn(i:3);
{Boucle interne à la recherche du plus petit élément}
for j:=i+1 to Tab_Tri.Limit do Begin
{Cas où l'élément courant est plus petit que le plus petit rencontré}
if Tab_Tri.travail[j].Ref<Tab_Tri.travail[i].Ref then Begin
{Permutation}
temp:=Tab_Tri.travail[i];
Tab_Tri.travail[i]:=Tab_Tri.travail[j];
Tab_Tri.travail[j]:=temp;
End;
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
129
End;
End;
{Pour faire apparaître le numéro du dernier élément trié}
Gotoxy(1,8); WriteLn(i+1:3);
End;
Procedure RECOPIER;
{Cette procédure copie le vecteur de travail trié dans le fichier Mj_Ide}
Var
FIden : file of TIden;
i : integer;
Begin
{Affichage informatif à destination de l'utilisateur}
Gotoxy(1,9); WriteLn('Début de la recopie du tri.');
{Remise à zéro du fichier Mj_Ide pour y copier le résultat du tri}
Assign(FIden, 'C:\Bruno\Kwic\Mj_Ide');
Rewrite(FIden);
{Boucle de parcours du vecteur trié}
for i:=1 to Tab_Tri.Limit Do Begin
Gotoxy(1,10); WriteLn(Tab_Tri.Limit:3);
Write(FIden, Tab_Tri.travail[i]);
End;
{Fermeture du fichier}
Close(FIden);
End;
{DEBUT DU PROGRAMME PRINCIPAL}
Begin
{Annonce du programme à l'utilisateur}
ClrScr;
WriteLn('KWIC : Programme de tri du catalogue des identifications du mois');
WriteLn('****************************************************************');
WriteLn;
Write('Voulez-vous continuer (O=Oui) :');
ReadLn(Rep);
if Rep='o' then Rep:='O';
{Cas où l'utilisateur abandonne}
if Rep <> 'O' then WriteLn('Tri non fait !')
else Begin
{Chargement du fichier dans le vecteur Tab_Tri}
Charger;
{Tri du vecteur Tab_Tri}
Trier;
{Recopie du vecteur trié dans Mj_Ide}
Recopier;
WriteLn('Tri terminé !');
End;
End.
Figure A11.8. Le programme Triden
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
130
A11.5. LES PROGRAMMES DE FUSION
La troisième étape, et dernière, de la phase d'intégration des références des
documents dans la base du KWIC est la fusion avec la base du KWIC des trois
fichiers : Mj_Ide, Mj_Aut et Mj_Mot créés par les programmes de tris.
KWIC : programme de fusion du catalogue identification du mois dans la base
**************************************************************
Entrez le numéro de version à créer (0=arrêt) :
Figure A11.9. Ecran d'accueil du programme FusIden
Le programme FusIden de la figure A11.10 réalise ce traitement pour le fichier
Mj_Ide. Nous laissons le soin au lecteur de le 'couper-coller' et de l'adapter pour
obtenir les programmes qui permettront la fusion avec la base KWIC des deux
autres fichiers : Mj_Aut et Mj_Mot. La figure A11.6 présente l'écran d'accueil qui
s'affiche au lancement de ce programme.
Program FUSIDEN;
{
Le but de ce programme est de fusionner le catalogue des identifications du mois,
Mj_Ide, avec le catalogue de la base KWIC correspondant Ide_xxx
}
Uses
Dos, Crt;
Type
TIden = record
Ref : string[10];
Auteurs : string[110];
Titre : string[120];
End;
Var
Nos_Version : longint;
F1, F2, FResult : file of TIden;
Enr1, Enr2 : TIden;
Fini1, Fini2 : boolean;
Function INIT_F1: boolean;
{Ouverture du catalogue du mois et lecture de son premier enregistrement}
Begin
{Ouverture du catalogue du mois}
Assign(F1, 'C:\Bruno\Kwic\Mj_Ide');
Reset(F1);
{Test si on a (déjà !) atteint la fin du fichier}
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
131
if eof(F1) Then
{L'initialisation a échouée}
Init_F1:=false
else Begin
{Lecture du premier enregistrement}
Read(F1, Enr1);
{L'initialisation a réussie}
Init_F1:=true;
End;
End;
Function INIT_F2: boolean;
{Ouverture du catalogue actuel et lecture de son premier enregistrement}
Var travail : string;
Begin
{Conversion en chaîne de caractère du numéro de version du catalogue
actuel}
Str(Nos_Version-1, travail);
While length(travail)<3 do travail:='0'+travail;
{Ouverture du fichier}
Assign(F2, 'C:\Bruno\Kwic\Ide_'+travail);
Reset(F2);
{Lecture du premier enregistrement}
if eof(F2) Then
init_F2:=false
else Begin
init_F2:=true;
Read(F2, Enr2);
End;
End;
Procedure INIT_RESULT;
{Création du future catalogue}
Var Travail : string;
Begin
{Conversion en chaîne de caractère du numéro de version du futur
catalogue}
str(Nos_Version, travail);
While length(travail)<3 do travail:='0'+travail;
{Création du future catalogue}
Assign(FResult,'C:\Bruno\Kwic\Ide_'+travail);
Rewrite(FResult);
End;
Procedure VIDAGE_F1;
{Copie de la fin du catalogue du mois dans le futur catalogue}
Begin
While Fini1=false do Begin
Write(FResult, Enr1);
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
132
if eof(F1) then
Fini1:=true
else
Read(F1, Enr1);
End;
End;
Procedure VIDAGE_F2;
{Copie de la fin du catalogue du mois dans le futur catalogue}
Begin
While Fini2=false do Begin
Write(FResult, Enr2);
if eof(F2) then
Fini2:=true
else
Read(F2, Enr2);
End;
End;
{DEBUT DU PROGRAMME PRINCIPAL}
Begin
{Annonc du programme à l'utilisateur}
ClrScr;
WriteLn('KWIC : programme de fusion du catalogue identification du mois dans la
base KWIC');
WriteLn('*********************************************************************
***********');
WriteLn;
{Saisie du numéro de la version du catalogue à créer}
Write('Entrez le numéro de la version à créer (0=arrêt) :');
ReadLn(Nos_Version);
{Cas où l'utilisateur veut continuer}
if Nos_Version<>0 Then Begin
{Ouverture et lecture du premier enregistrement du catalogue du mois}
Fini1:=not Init_F1;
{Ouverture et lecture du premier enregistrement du catalogue actuel}
Fini2:=not Init_F2;
{Création à vide du future catalogue}
Init_Result;
{Fusion tant que les deux fichiers à fusionner ne sont pas fini}
While (not Fini1) and (not Fini2) do Begin
{Cas où le dernier enregistrement lu dans le catalogue du mois est
plus petit que celui lu du catalogue actuel}
if Enr1.Ref<Enr2.Ref then Begin
{Ajout dans le futur catalogue}
Write(FResult, Enr1);
{Lecture de l'enregistrement suivant dans le catalogue du mois}
if not eof(F1) then
Read(F1, Enr1)
else
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
133
Fini1:=true;
{Cas où le dernier enregistrement lu dans le catalogue actuel est
plus petit que celui du catalogue du mois}
End else Begin
{Ajout dans le futur catalogue}
Write(FResult, Enr2);
if not eof(F2) then
Read(F2, Enr2)
else
Fini2:=true;
End;
End;
{Copie de la fin du premier fichier dans le fichier résultat}
Vidage_F1;
Vidage_F2;
{Fermeture des fichiers}
Close(F1);
Close(F2);
WriteLn('Fusion terminée !');
End;
End.
Figure A11.10. Le programme FusIden
A11.6. LES PROGRAMMES D'IMPRESSION
Les catalogues finaux : identification, auteur et mot-clef à jour peuvent être
imprimées
Programme d''impression du catalogue des identifications du projet KWIC
**************************************************************
Entrez le numéro de la version à imprimer (0=arrêt) :
Figure A11.11. Ecran d'accueil du programme
Le programme ImpIde de la figure A11.12 réalise ce traitement pour le fichier
Ide_001. Nous laissons le soin au lecteur de le 'couper-coller' et de l'adapter pour
obtenir les programmes qui permettront la fusion des deux autres fichiers, Aut_xxx
et Mot_xxx, avec la base KWIC. La figure A11.11 présente l'écran d'accueil qui
s'affiche au lancement de ce programme.
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
134
Program IMPIDE;
{
Le but de ce programme est d'imprimer le catalogue des identifications du projet
KWIC
}
Uses
Dos, Crt;
Type
TIden = record
Ref : string[10];
Auteurs : string[110];
Titre : string[120];
End;
Var
FIden : file of TIden;
Enr_FIde : TIden;
Nos_Version : integer;
FImp
: text;
Travail : string;
Nos_Page, Nos_Ligne : integer;
Begin
{Annonce du programme à l'utilisateur}
ClrScr;
WriteLn('Programme d''impression du catalogue des identifications du projet
KWIC');
WriteLn('*********************************************************************
**');
WriteLn;
{Saisie du numéro de la version du catalogue à imprimer}
Write('Entrez le numéro de la version à imprimer (0=arrêt) :');
ReadLn(Nos_Version);
if Nos_Version<>0 Then Begin
{Conversion du numéro saisie sous forme de chaîne de caractères}
str(Nos_Version, Travail);
{Mise sur trois caractères du numéro de version}
While length(travail)<3 do travail:='0'+travail;
{Ouverture du fichier à imprimer}
Assign(FIden,'C:\BRUNO\kwic\ide_'+Travail);
Reset(FIden);
{Ouverture de l'imprimante}
Assign(FImp,'prn');
Rewrite(FImp);
{Mise à zéro du compteur du numéro de page d'impression}
Nos_Page:=0;
{Boucle de parcours du fichier Fiden}
While not eof(FIden) Do Begin
{Mise à zéro du compteur du numéro de ligne dans la page}
Nos_Ligne:=0;
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
135
{Incrémentation du compteur de numéro de page}
Nos_Page:=Nos_Page+1;
{Impression du haut de page}
WriteLn(FImp, 'Catalogue des identifications. Page numéro :', Nos_Page:3);
{Boucle d'impression d'une page, i.e. une suite d'au plus 60 lignes}
While (not eof(FIden)) and (Nos_Ligne<60) do Begin
{Lecture de l'enregistrement}
Read(FIden, Enr_FIde);
{Impression du contenu de l'enregistrement courant}
WriteLn(FImp, Enr_FIde.Ref+'*'+Enr_FIde.Auteurs+'*'+
Enr_FIde.Titre);
{Incrémentation du compteur du nombre de lignes imprimées}
Nos_Ligne:=Nos_Ligne+1;
End; {Fin du While}
End; {Fin du While}
{Fermeture des fichiers}
Close(FIden);
Close(FImp);
End;
End.
Figure A11.12. Le programme ImpIde
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
136
Annexe 12
Correction des exercices du
chapitre 12
EXERCICE 1
Program SLST;
{
Ce programme est destinée à illustrer l'utilisation des pointeurs. Il permet de saisir une
liste (potentiellement infinie) de chaînes de caractères, puis en fin de saisie, d'afficher
cette liste autant de fois de fois que le désire l'utilisateur.
Le fait que la liste entrée soit potentiellement infinie oblige à utiliser les pointeurs au
lieu d'une variable dimensionnée
}
Uses Crt,Dos;
TYPE
PBufferTexte= ^TBufferTexte;
TBufferTexte=record
Texte : string;
Suivant: PBufferTexte;
End;
VAR
ListeChaine : PBufferTexte;
{Mémorise la liste de chaîne saisie }
NbRepet : integer;
{Nombre de fois qu'il faut afficher les
chaînes de
caractères saisies}
I : integer;
{Variables de travail }
Ch : string;
Function AncPrg:char;
{Annonce du programme : Retourne 'N' si l'utilisateur veut arrêter le programme et
'O' sinon}
Var Rep : char; {Variable de travail}
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
137
Begin
{Affichage pour présenter le but du programme à l'utilisateur}
ClrScr;
GotoXy(15,1);
WriteLn('SAISIE ET AFFICHAGE DE CHAINE DE CARACTERES');
GotoXy(15,2); WriteLn('*******************************************');
GotoXy(1,4); WriteLn('Ce programme saisie une liste de chaînes de caractères');
GotoXy(1,5); WriteLn('Puis les affiche autant de fois que vous le désirez.');
GotoXy(1,15); WriteLn('Voulez-vous continuer (O-N):');
{Boucle pour forcer l'utilisateur à répondre 'O' ou 'N'}
Repeat
GotoXy(29,15); ClrEol;
ReadLn(Rep);
Rep:=UpCase(Rep);
until (Rep='O') or (Rep='N');
{Renvoie de la valeur à la fonction}
AncPrg:=Rep;
End;
Procedure SaisieListe;
{
Cette procédure saisie la liste des chaînes de caractères. Cette liste étant
potentiellement infinie, elle est mémorisée à l'aide d'une liste chaînée crée à l'aide de
pointeurs Pascal. L'insertion est faîte en fin de liste.
Remarque : l'insertion en fin de la chaîne est immédiate car le programme tient à jour
constamment un pointeur vers le dernier élément de la liste : LastListeChaine.
}
Var LastListeChaine : PBufferTexte;
{Pointe sur le dernier élément de la
liste}
NosLigne : integer;
{Numéro de la ligne saisie}
Ch : string;
{Variable de travail }
Begin
{Initialisations}
ListeChaine:=Nil;
NosLigne:=1;
{Boucle de saisie. Un tour de boucle ==> saisie d'une chaîne de caractères}
Repeat
{Affichage d'une invitation à entrer une chaîne de caractères}
GotoXy(1,24);
Write('Ligne numéro ',NosLigne:4,' (F=fin):');
ClrEol;
GotoXy(19,32);
{Saisie de la chaîne de caractères}
ReadLn(Ch);
{Cas où l'utilisateur a exprimé son désir d'arrêter}
if (Ch<>'F') then Begin
{Cas spécial de l'insertion de la première chaîne}
if ListeChaine=Nil then Begin {première chaîne}
{Création d'une cellule}
New(ListeChaine);
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
138
{Mémorisation de la chaîne de l'utilisateur dans la cellule créée}
ListeChaine^.Texte:=Ch;
{Le suivant du dernier est Nil}
ListeChaine^.Suivant:=Nil;
{Initialisation de LastListChaine : pointeur vers le dernier élément
de la liste qui ici est aussi le;premier (et les eul) élément}
LastListeChaine:=ListeChaine;
{Cas général : insertion des chaînes 2 et suivantes}
End Else Begin
{Création d'une cellule pointée par le suivant du dernier élément}
New(LastListeChaine^.Suivant);
{Mémorisation de la chaîne de l'utilisateur dans la cellule créée}
LastListeChaine^.Suivant^.Texte:=Ch;
{Insertion en fin de liste et le suivant du dernier est Nil}
LastListeChaine^.Suivant^.Suivant:=Nil;
{Mise à jour de LastListeChaine : pointeur sur le dernier élément}
LastListeChaine:=LastListeChaine^.Suivant;
End;
End;
{Mise à jour du compteur de chaîne mémorisée}
NosLigne:=NosLigne+1;
until (Ch='F');
End;
Procedure AfficheListe;
{
Affichage de la liste de chaîne de caractères mémorisée dans la liste chaînée pointée
par ListeChaîne
}
Var WPtr : PBufferTexte; {Variable de travail}
Begin
{Initialisation du pointeur de parcours}
WPtr:=ListeChaine;
{Boucle de parcours de la liste chaînée}
While WPtr<>Nil do Begin
{Affichage de la chaîne courante}
WriteLn(WPtr^.texte);
{Passage à la cellule suivante}
WPtr:=WPtr^.suivant;
End; {Fin du While}
End;
{DEBUT DU PROGRAMME PRINCIPAL}
Begin
{Annonce du programme à l'utilisateur}
If AncPrg='N' then EXIT;
{Saisie complète de la liste}
SaisieListe;
{Saisie du nombre de répétition d'affichage de la liste à effectuer}
GotoXy(1,24);
ClrEol;
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
139
GotoXy(1,24);
Write('Nombre de répétitions:');
ReadLn(NbRepet);
{Boucle permettant de sortir la liste le nombre de fois demandée}
For i:=1 to NbRepet do Begin
{Renseignement de l'utilisateur sur l'avancement des affichages}
WriteLn('Affichage numéro ',i:4,' Appuyez sur RETURN');
ReadLn(Ch);
{Affichage de la liste à l'écran}
AfficheListe;
End; {Fin du For}
End.
Figure A12.1. Liste chaînée avec pointeur
EXERCICE 2
Program A12_2;
{ Ce programme sert de support à la procédure Transform}
Type
M10 = array[1..10, 1..10] of real;
TPListe = ^TListe;
TListe = record
Ligne : integer;
Colonne : integer;
Valeur : real;
Suivant : TPliste;
End;
Var Ma_Matrice : TListe;
Procedure TRANSFORM(M:M10; Var Liste : TPListe);
Var i, j : integer;
Derniere_cellule : TPListe;
Ajout : TPListe;
Begin
{Initialisations}
Liste:=Nil;
Derniere_cellule:=Liste;
{Boucle de parcours de la ligne de la matrice M}
For i:=1 to 10 do
{Boucle de parcours des colonnes de la ligne i}
For j:=1 to 10 do Begin
{On ne mémorise que les valeurs différentes de zéro}
If M[i,j]<>0 Then Begin
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
140
End;
{Création d'une nouvelle cellule}
Ajout:=New(TPListe);
{Mémorisation des éléments de la case à mémoriser}
Ajout^.Ligne:=i;
Ajout^.Colonne:=j;
Ajout^.Valeur:=M[i,j];
Ajout^.Suivant:=Nil;
{Cas particulier de l'ajout de la première cellule}
If Liste=Nil Then Begin
Liste:=Ajout;
Derniere_Cellule:=Liste;
{Cas général : ajout des cellules 2 et suivantes}
End Else Begin {rappel : ajout en fin de liste}
Derniere_Cellule^.Suivant:=Ajout;
Derniere_Cellule:=Ajout;
End;
End;
End; {Fin du For}
{DEBUT DU PROGRAMME PRINCIPAL}
Begin
{L'écriture du programme principal est laisséà la discrétion du lecteur : question
non demandée}
End.
Figure A12.2. La procédure Transform
EXERCICE 3
Program PRENOM;
{Le but du programme proprement dit est de remplir et afficher une structure de
données pour menu déroulant avec un seul niveau de sous-menu. Ici des noms et des
prénoms.
Mais le but réel de cet exercice technique est de mettre en évidence la 'souplesse'
permise si un paramètre de procèdure est une liste chaînée réalisée à l'aide de pointeur
(voir le programme principal.
}
Uses Dos,crt;
Type
{Types déclarés autant par obligation pour des problèmes de passage de
paramètres que par souci de rigueur}
TPCellMenu = ^TCellMenu;
{Type:Pointeur vers une cellule de menu}
TPCellSMenu = ^TCellSMenu; {Type:Pointeur vers une cellule de sous-menu}
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
141
String50
= string[50];
{Cellule de menu}
TCellMenu = Record
Libelle :string[50]; {Libellé du choix du menu}
PCellSMenu :TPCellSMenu; {Pointeur vers le premier sous-choix}
PCellMenu :TPCellMenu; {Pointeur vers le choix suivant}
End;
{Cellule de sous-menu}
TCellSMenu= Record
Libelle :string[50]; {Libellé du choix du sous-menu}
PCellSMenu :TPCellSMenu; {Pointeur vers le sous-choix suivant}
End;
Var
{Variables de travail}
PMenu : TPCellMenu; {Pointeur vers une cellule d'un menu}
WPTr1 : TPCellMenu; {Variables de travail pour affichage de contrôle}
WPtr2 : TPCellSMenu;
Function NewChoix(
Libelle:string50;
P1: TPCellSMenu;
P2: TPCellMenu)
: TPCellMenu;
{
Création d'une cellule 'menu' initialisée avec les paramètres Libelle, P1 et P2. La
fonction retourne l'adresse de la cellule crée
}
Var WPtr : TPCellMenu ; {Variable de travail}
Begin
{Création d'une nouvelle cellule}
WPtr:=New(TPCellMenu);
{Initialisation de la cellule créée avec Libelle, P1 et P2}
WPtr^.Libelle:=Libelle;
WPtr^.PCellSMenu:=P1;
Wptr^.PCellMenu:=P2;
{Renvoie à la fonction de "l'adresse" de la cellule créée et rempli}
NewChoix:=WPtr;
End;
Function NewSChoix(
Libelle:string50;
P1: TPCellSMenu)
: TPCellSMenu;
Var WPtr : TPCellSMenu; {Variable de travail}
Begin
{Création d'une nouvelle cellule}
WPtr:=New(TPCellSMenu);
{Initialisation de la cellule créée avec Libelle et P1}
WPtr^.Libelle:=Libelle;
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])
142
WPtr^.PCellSMenu:=P1;
{Renvoie à la fonction de "l'adresse" de la cellule créée et rempli}
NewSChoix:=WPtr;
End;
{DEBUT DU PROGRAMME PRINCIPAL}
Begin
ClrScr;
{Initialisation du menu complet en une seule instruction !}
PMenu:= NewChoix('DUPONT',
NewSchoix('Pierre',
NewSChoix('Paul',
NewSChoix('Jacques',
NewSChoix('Gaston',Nil)))),
NewChoix('DURAND',
NewSchoix('Sophie',
NewSchoix('André',
NewSchoix('Bruno',
NewSchoix('Laurent',
NewSchoix('Hortense',Nil))))),
NewChoix('INCONNU',Nil,
NewChoix('TANDIER',
NewSchoix('Emile',Nil),
Nil))));
{Initialisation}
WPtr1:=PMenu;
{Boucle de parcours et d'affichage pour vérification de la structure créée}
While WPtr1<>Nil do Begin
{Affichage du champ Libelle d'un menu}
WriteLn(WPtr1^.Libelle);
{Isolement du pointeur vers la liste des sous-menus}
WPtr2:=WPtr1^.PCellSMenu;
{Boucle d'affichage des sous-menus}
While WPtr2<>Nil Do Begin
{Affichage du Libelle du sous-menu courant}
WriteLn(' ',Wptr2^.libelle);
{Passage au sous-menu suivant}
WPtr2:=WPtr2^.PCellSMenu;
End;
{Passage au menu suivant}
WPtr1:=WPtr1^.PCellMenu;
End;
End.
Figure A12.3. Le programme Prenom
Introduction à l'informatique et à l'algorithmique (Correction des exercices)
Bruno Warin ([email protected])

Documents pareils