• Aucun résultat trouvé

NF01 - Automne 2010 Examen Final - 2 heures

N/A
N/A
Protected

Academic year: 2022

Partager "NF01 - Automne 2010 Examen Final - 2 heures"

Copied!
9
0
0

Texte intégral

(1)

NF01 - Automne 2010

Examen Final - 2 heures

Problème n°1 (8 points)

On souhaite gérer un tableau de personnes, chacune étant déterminée par son nom, son prénom, son âge, son téléphone et sa ville de résidence. On admet que ce tableau a déjà été constitué par un stockage initial et a déjà été trié selon l‟ordre alphabétique des noms (on suppose donc que les personnes ont toutes des noms différents). Voici les actions à mener :

(1 pt) : Faites en Pascal les déclarations de Types correspondant à ces structures de données.

Solution :

const

{nombre maxi de personnes dans un tableau}

Nmax = 1000;

type

{ une personne } personne = record

nom : string[20];

prenom : string[20];

ville : string[20];

age: integer;

tel : integer;

end;

{ plusieurs personnes }

tableau = array[1..Nmax] of personne;

{ un fichier de personne } fich_pers = file of personne;

(2 pts) : Ecrire une procédure SUPPRESSION qui, ayant en entrée le tableau et un nom, permette de supprimer du tableau la personne de ce nom : on prendra soin de ne jamais laisser de case vide, donc de repositionner tous les éléments suivants par décalage „à gauche‟.

Solution :

{---SUPPRESSION--- fonction suppression: donné un tableau de personnes et un "nom", cherche "nom" dans le tableau. Si la personne de nom "nom" est trouvé, cette personne est enlevée du tableau

(2)

entrée: tab un tableau de Nmax elements nb_pers: nombre d'éléments dans tab

nom : le nom de la personne à rechercher et à être enlevée de tab

sortie: tab modifié si la personne existe dans le tableau, tab inchangé si la personne n'est pas dans le tableau (ce fait est indiqué à l'utilisateur par un message à l'écran)

---}

procedure suppression(var tab: tableau; var nb_pers : integer; nom : string[20]);

var

ind_pers, i : integer;

begin

{cherche la personne dans le tableau}

ind_pers := recherche(tab, nb_pers, nom);

if ind_pers = 0 then

writeln('La personne de nom : ', nom, ' n''est pas dans la liste de personnes') else begin

{suppresion de la personne à la position ind_pers dans le tableau}

for i := ind_pers to (nb_pers - 1) do tab[i] := tab[i+1];

nb_pers := nb_pers - 1;

end;

end;

(2 pts) : Ecrire une procédure AJOUT qui permette d‟ajouter à ce tableau une nouvelle personne, au bon endroit alphabétique : il faudra alors décaler les éléments suivants „à droite‟.

Solution :

{---AJOUT--- fonction ajout:

donné un tableau de personnes et une personne, cherche personne dans le tableau. Si l'élément personne n'est pas trouvé, et s'il y a encore de la place dans la liste, cette personne est ajoutée dans le tableau

entrée: tab un tableau de Nmax elements nb_pers: nombre d'éléments dans tab

nouveau_inscrit : la personne à être rajoutée dans tab, si possible sortie: tab modifié si la personne y est ajoutée, tab inchangé

si la personne est déjà dans tab ou s'il n'y a plus de place pour ajouter une personne

hypothèse : tab est déjà trié par ordre alphabétique des noms des personnes ---}

procedure ajout(var tab: tableau; var nb_pers : integer; nouveau_inscrit : personne);

var

i, j : integer; {variables des boucles}

(3)

ind_pers : integer;

begin

{cherche la personne dans le tableau}

if nb_pers = Nmax then

writeln('Il n''y a plus de place, la liste de personnes et pleine') else begin

ind_pers := recherche(tab, nb_pers, nouveau_inscrit.nom);

if ind_pers <> 0 then

writeln('La personne de nom : ', nouveau_inscrit.nom, ' est déjà dans la liste de personnes')

else begin

{insere la personne dans la bonne case (hyp.: le tab est déjà trié par ordre alf.)}

i := 0;

repeat i := i+1;

until (nouveau_inscrit.nom < tab[i].nom) or (i > nb_pers);

if i <= nb_pers then

for j := nb_pers downto i do

tab[j+1] := tab[j]; {ouvre une position à i, avec le decalage vers la fin du tableau}

{insere la personne à la case i}

tab[i] := nouveau_inscrit;

nb_pers := nb_pers + 1;

end;

end;

end;

(1 pt) : Ecrire une procédure SAUVEGARDE qui permette de sauvegarder le tableau dans un fichier.

Solution :

{---SAUVEGARDE--- fonction sauvegarde:

donné un tableau de personnes, sauvegarde toutes les personnes dans un fichier de personnes (fichier binaire)

entrée: tab un tableau de Nmax elements nb_pers: nombre d'éléments dans tab

sortie: un fichier de personnes créé

---}

procedure sauvegarde(tab: tableau; nb_pers : integer);

var

i : integer; {variable de boucle}

begin

(4)

{ouverture d'un fichier en mode création-écriture}

assign(fp, 'fichier_de_personnes.bin');

rewrite(fp);

{écriture de toutes les personnes dans le fichier}

for i:= 1 to nb_pers do write(fp,tab[i]);

{fermeture du fichier}

close(fp);

end;

(1 pt) : Ecrire une procédure AFFICHAGE qui permette d‟afficher les coordonnées (nom, prénom, âge, téléphone, ville) de toutes les personnes du fichier.

Solution :

{---AFFICHAGE--- procedure affichage:

affiche les données des personnes sauvegardées dans un fichier

entrée: fichier de personnes enregistrée dans le disk

sortie: affichage des caractéristiques des personnes à l'écran ---}

procedure affichage;

var

i : integer; {variable de boucle}

pers : personne; {une personne}

begin

{ouverture d'un fichier en mode lecture}

assign(fp, 'fichier_de_personnes.bin');

reset(fp);

{lecture des personnes et affichage à l'écran}

i := 0;

writeln('--- Personnes inscrites ---');

writeln('---- nom---prénom---age---num tél---ville---');

while not eof(fp) do begin read(fp, pers);

i := i+1;

writeln(' ',i,' : ', pers.nom,' ',pers.prenom,' ', pers.age,' ', pers.tel,' ', pers.ville);

end;

{fermeture du fichier}

close(fp);

end;

(1 pt) : Ecrire une procédure TRANSFERT qui permette de récupérer les données sauvegardées dans le fichier et de les transférer dans un tableau.

(5)

Solution :

{---TRANSFERT--- procedure transfert:

rempli un tableau de personnes inscrites dans un fichier

entrée: fichier de personnes enregistrée dans le disk sortie: tab contenant les personnes inscrites dans le fichier ---}

procedure transfert(var tab: tableau; var nb_pers : integer);

var

pers : personne; {une personne}

begin

{ouverture d'un fichier en mode lecture}

assign(fp, 'fichier_de_personnes.bin');

reset(fp);

{lecture des personnes et remplissage de tab}

nb_pers := 0;

while not eof(fp) do begin read(fp, pers);

nb_pers := nb_pers+1;

tab[nb_pers] := pers;

end;

{fermeture du fichier}

close(fp);

end;

PS : on portera la plus grande attention à la définition des arguments de ces procédures.

(6)

Problème n°2 (7 points)

Dans cette partie, nous supposerons que les chaînes de caractères comportent uniquement des caractères majuscules, minuscules et le caractère « blanc ». Les chaînes ne dépassent pas 255 caractères.

1. (1pt) Faire une fonction majuscule qui reçoit une chaîne et renvoie une nouvelle chaîne en ayant transformé les caractères minuscules en majuscules.

function majuscule(s : string):string;

var i : integer;

begin

for i:=1 to length(s) do if ((s[i]>='a') and (s[i]<='z'))

then

s[i] := chr(ord(s[i])-ord('a')+ord('A'));

majuscule := s;

end;

2. (1pt) Faire une fonction enleve_blanc qui reçoit une chaîne et qui retourne une chaîne en ayant enlevé tous les caractères blancs.

function enleve_blanc(s: string ):string;

var i : integer;

begin

i := pos(' ',s);

writeln(i,s);

while (i <> 0) do begin

s := copy(s,1,i-1) + copy(s,i+1,length(s)-i);

i := pos(' ',s);

writeln(s);

end;

enleve_blanc := s;

end;

3. (1pt) Faire une fonction duplique qui reçoit une longueur M et une chaîne K telle que length(K)<M et qui retourne une chaîne dans laquelle on répète la chaîne K autant de fois que nécessaire pour atteindre exactement la longueur de M. Exemple : M = 17 et K = 'bonjour', on obtient la chaîne 'bonjour bonjourbo'

function duplique(K : string ; l : integer):string;

(7)

var s_result : string;

i,ent, rest : integer;

begin

s_result := '';

ent := l div length(K);

rest := l mod length(K);

for i:= 1 to ent do s_result := s_result + K;

s_result := s_result + copy(K,1,rest);

duplique := s_result;

end;

4. (4pts) A l'aide des fonctions créées, traiter le problème suivant :

Chiffre de Vigenère : Le chiffre de Vigenère est une méthode de chiffrement simple, du type substitution polyalphabétique, c'est-à-dire qu'une lettre donnée de l'alphabet dans le message original peut donner lieu à différentes lettres dans le message chiffré, en fonction de sa position.

Notons M le message original, K la clé, et C le message chiffré. M, K et C sont des chaînes de caractères en majuscules.

Intuitivement, la méthode fonctionne de la manière suivante : on écrit le message M, et sous M, on répète la clé K autant de fois que nécessaire pour atteindre la longueur de M. On décale alors chaque lettre de M d'une valeur correspondant à la lettre associée à K (0 pour A, 1 pour B, etc., en

“bouclant” sur A après Z) pour former le message chiffré C. Pour l'exemple nous avons volontairement laissé les caractères blancs pour que vous compreniez mieux. Ils ne doivent pas apparaître normalement.

Exemple : M = "EXERCICE DE PROGRAMMATION", K = "VIGENERE"

M: EXERCICE DE PROGRAMMATION K: VIGENERE VI GENEREVIGENER C: ZFKVPMTI YM VVBKIEHUGXVSE

Formellement, en notant n la fonction qui associe son numéro à une lettre de l'alphabet (0 pour A, 1 pour B, etc.), on a pour chaque lettre d'indice i du message :

n(Ci) = n(Mi) + n(Ki) [mod 26]

Écrire une fonction qui prend en entrée un message, une clé, et fournit la version chiffrée du message. Pour faciliter la lecture nous avons écrit la chaîne M en majuscules et conservé les caractères blancs, mais il faut mettre la chaîne en majuscules et enlever les caractères blancs.

program inconnu;

const MAX = 10;

var i : integer;

M,s3,K ,r: string;

(8)

function vigenere(M,K : string ):string;

var r : string;

i, val : integer;

begin r := M;

for i:= 1 to length(M) do begin

val := ord(M[i])-ord('A');

val := val + ord(K[i])-ord('A');

val := val mod 26;

r[i] := chr(val + ord('A'));

end;

vigenere := r;

end;

begin

s3 := majuscule('exercice de programmation');

writeln('Le s3 est : #',s3,'#');

s3 := enleve_blanc(s3);

writeln('Messages sans Blanc : #',s3,'#');

M := s3;

K := 'VIGENERE';

K := duplique(K , length(M));

writeln('M est : #',M,'#');

writeln('K est : #',K,'#');

r := vigenere(M,K);

writeln('Le resultat est : #',r,'#');

readln;

end.

(9)

Problème n°4 (5 points)

Un principe connu depuis fort longtemps permet d‟effectuer la multiplication de deux entiers naturels a et b. Il est défini comme suit :

- si b vaut 0 alors : a b est égal à 0

- si b est impair alors : a b est égal à a + a (b – 1) - si b est pair alors : a b est égal à (a + a) (b / 2)

1. Ecrire une fonction récursive nommée produit qui applique ce principe pour multiplier deux nombres entiers a et b.

2. Faire une simulation avec a = 4, b = 3.

1) Soit la fonction récursive suivante :

function MULT(a,b : integer) : integer;

begin

if b = 0

then MULT := 0 else if (b mod 2 = 0)

then MULT := MULT(a + a, b div 2) else MULT := a + MULT(a, b-1);

end end ;

2) Simulation :

Appel de MULT avec a=4 et b=3 b mod 2 = 1

MULT ← 4 + MULT(4,2)

Appel de MULT avec a=4 et b=2 b mod 2 = 0

MULT ← MULT(8,1)

Appel de MULT avec a=8 et b=1 n mod 2 = 1

MULT ← 8 + MULT(8,0)

Appel de MULT avec a=8 et b=0 MULT ← 0

Fin de MULT MULT ← 8

Fin de MULT MULT ← 8

Fin de MULT MULT ← 12

Fin de MULT

Références

Documents relatifs

et 2.3., identifier sur le diagramme des blocs internes, les flux d’énergies circulants dans le système dans le cas d’un réglage par l’habitacle de la voiture et surligner les

chaine[debut:fin] Renvoie la partie de chaine comprise entre le caractère à la positon debut (inclus) et celui à la position fin (exclu). Transformer une chaîne de

Appliquer la relation de Bernoulli entre les points 1 et 2 en négligeant tout frottement entre ces deux points (notamment au point A). Des stations de pompage sont

Une pile est représentée par une structure regroupant un entier, pour le sommet, et un tableau de MAX_PILE éléments (ici, des caractères). II.1- En utilisant la

Nous postulons que le rôle de l’État, c’est-à-dire de l’organisation que nous nous donnons pour faire valoir l’intérêt général, est certes de financer

• Lorsque certains intermédiaires réactionnels, très réactifs, interviennent en quantité très restreinte (reconsommés dès quʼil se forment), on peut être tenté

• Le CO 2 contenu dans l'air se dissout dans la solution ; on peut raisonnablement supposer que la quantité est proportionnelle au volume de solution de soude (dissolution

• Comme on peut le voir sur le diagramme logarithmique ci-après, les mesures indiquées semblent hélas toutes correspondre à la zone de raccordement entre les