CPY Document

publicité
EXAMEN PROFESSIONNEL DE VERIFICATION D' APTITUDE
AUX FONCTIONS DE PROGRAMMEUR
Annee 2004
Date de l' epreuve : 03 mai 2004.
Epreuve ecrite :
Etablissement de l' algorithme (sous forme d' ordinogramme) correspondant il la solution
probleme simple et ecriture des sequences de programme demandees
un
correspondantes , dans le langage C++.
Duree 5 heures - coefficient 4.
Avant de commencer il composer, verifiez que le sujet qui vous a ete remis comporte cinq
pages (non comprise celle- ci) ; le cas echeant , signalez aux surveilants toute anomalie.
Bareme de notation'
Les questions 1 il 4 : 2 points;
les questions 5 il 16 . 1 point par question;
les questions 17 il 20 : 6 points.
Nota : les questions sont independantes et peuventetre traitees non sequentiellement.
.(.(
Codage de Huffman
document electronique il est souvent tres pratique de compresser ce
document prealablement afin de diminuer le volume des donnees a transferer et sans alterer son
contenu. Dans ce sujet vous allez developper une methode de compression tres efficace , appelee
Pour transmettre ou stocker un
codage de Huffman d' apres le nom de son inventeur.
Le code de Huffman s applique principalement a la compression de donnees textuelles. Son principe
est le suivant dans l' ordinateur chaque caractere de l' alphabet est represente par un chiffre
variant entre 0 et 255 (le code ASaI).
Ce chiffre exprime en base 2 correspond CI une serie de 8
bits. Par exemple pour le caractere ' ' on aura le code 01100001. Ainsi pour enregistrer un texte de n
caracteres dans l' ordinateur on a generalement besoin de 8n bits. Le but du codage de Huffman est
de reduire le nombre de bits necessaire pour chaque caractere. Plus precisement le nombre de bits
necessaire va devenir une fonction de la frequence du caractere dans le texte CI compresser: plus un
caractere est frequent moins il faudra de bit pour le coder. Le codage se deroule en trois phases:
tout d' abord on commence par compter le nombre d' occurrences de chaque caractere , Puis en
utilisant ces occurrences , on construit un arbre binaire dont les feuilles sont les caracteres ; cet
arbre permet d' associer CI chaque caractere un code binaire optimal, enfin dans la troisieme etape
on remplace chaque caractere dans
le texte par son code optimal.
Arbres binaires.
Le but est de programmer une classe
((TNoeudBinaire))
representant les arbres binaires. Un
arbre
binaire est un arbre tel que chaque nreud a au plus deux descendants: un CI gauche et un CI droite.
arbre binaire represente ci contre (fig 1) comporte 5 nreuds notes ((A , B
E)) Le nreud ((A )) a deux descendants. (( B)) CI gauche et ((C)) CI droite.
, D,
Le nreud ((B )) a deux descendants (.(D )) a gauche et .(.(E )) a droite.
nreuds .(C , D , E)) n ont aucun descendant , ce sont des feuilles.
La classe
.(TNoeudBinaire))
Enfin les
que vous allez programmer permet de
representer recursivement les arbres binaires. Chaque instance de
Fig 1 : Arbre binaire
)) possede quatre variables une pour le contenu du nreud
((TNoeudBinaire
gauche et droite pour les deux descendants
(.(TNoeudBinaire))
parent pour le nreud directement au- dessus. Par exemple pour l' arbre figure 1 le nreud (.( B)) a pour
descendant gauche et droit respectivement.(.( D)) et.( E)) et pour parent le nreud .( A )) quant CI lui
a pas de parent (c est la racine).
deux
.((TNoeudBinaire))
1.
, et enfin un
Ecrire un constructeur pour la classe
contenu. Ce
2.
)) prenant en parametre un Object
.(.(TNoeudBinaire
constructeur construit un nouveau nreud contenant l' objet
contenu , n
ayant
ni parent , ni descendant.
Ecrire un constructeur pour la classe
prenant en parametre un object
(.(TNoeudBinaire))
gauche et droite. Ce constructeur construit
contenant l' objet contenu et dont les branches gauche et droite sont
respectivement gauche et droite.
))) renvoyant
.(.(TNoeudBinaire))
appelant n a pas de descendants CI gauche ni CI droite.
contenu et deux
((TNoeudBinaire))
.(.(TNoeudBinaire))
3.
4.
Ecrire une methode ((
Ecrire une methode.((
appelant n
EstUneFeuile(
EstLaRacine(
true
))) renvoyant.(
true
)) si le
)) si le
((TNoeudBinaire))
a pas de parent.
1/5
.(.(
))n et un objet obj on veut savoir dans quel nreud de
arbre de sommet n est contenu l' objet obj. Pour cela on applique l' algorithme suivant
Etant donne une.((TNoeudBinaire
Donnees'
- un nreud n
Resultat Le nreud de l' arbre de sommet n
- un objet obj
a pour valeur NULL si obJ n est pas
contenu dans l' arbre de sommet
dans lequel est contenu obj ou le pointeur
Algorithme:
- Si n contient obj alors renvoyer n
- Si le descendant gauche de n n est pas NULL appliquer l' algorithme au descendant gauche de
Si le resultat n est pas NULL retourner le resultat
- Si le descendant droit de n n est pas NULL appliquer l' algorithme au descendant droit de n.
Si le resultat n est pas NULL renvoyer le resultat.
- Si non renvoyer NULL
Ecrire une methode .((TNoeudBinaire * find(Object obj)))
appliquant cet algorithme au nC2ud
appelant.
6. La profondeur d' un nreud n est le nombre de nreud au- dessus de n dans l' arbre qui le
contient. Par exemple dans l' arbre de la figure 1 , la profondeur de (.( A ) est de 0 ,
la
profondeur de.(.( B)) et
C)) est de l, Programmer une methode renvoyant la profondeur
du nreud appelant de l' arbre qui le contient.
ArbreBinaire avec poids
Dans la suite nous aurons besoin de comparer des arbres binaires afin de pouvoir
Pour cela
TNoeudBinaire)) une nouvelle donnee membre poids de type entier.
CompareTo)) CI la classe ((TNoeudBinaire))
nous allons ajouter a la classe
7.
Ajouter une methode
les trier
Codage binaire des caracteres
A chaque caractere correspond un nombre en base 2 comportant 8 chiffres (enparticulier la valeur
representee par ce nombre est comprise entre 0 et 255). Etant donne un caractere ' ' il suffit pour
obtenir le code Asar correspondant de transtyper ' en int. Une fois ce transtypage effectue , la
representation binaire de ' est tout simplement egale a la representation binaire du code Asar
correspondant CI ' ' Ainsi le code Asar ' i' et la representation binaire.(.(
CoC1 C 2
)) sont
lies par l' equation
16c3+8c4+4c5+2C6+ lc7
Developpez une methode permettant d' obtenir un caractere a partir de son code binaire.
i= 128co + 64cl +32c 2+
Lecture d'
une chaine de caracteres bit
Etant donne une chalne de caractere ,
ci
bit
vous pouvez acceder CI n importe quel caractere de la chalne.
Malheureusement pour le codage de Huffman il faut pouvoir lire la chalne de caractere bit
est CI dire que chaque caractere sera lu sous
forme de 8 chiffres entre 0 et
a bit.
1. Pour pouvoir faire
cela simplement vous allez programmer une classe.(.( TBitStringReader ))
2/5
.(.(
.(.(
(.(
9. Ecrire
un constructeur de la classe
-(.(
prenant en parametre le texte
TBitStringReader))
CI lire.
10. Ecrire une methode.(
))) permettant d' obtenir un a un les bits composant le
ReadBit(
methode renvoie le prochain bit de la chaine de caractere). Pour
indiquant la position du caractere
actuellement lu et une autre variable indiquant la position du prochain bit a lire. Pour
texte (chaque appel
CI la
cela vous utilisez une variable de type entier
chaque caractere la
methode.(.(
))) renvoie un a un les bits composant le code
ReadBit(
binaire du caractere , avant de passer au caractere suivant
11. Ecrire une methode
) renvoyant vrais s il reste des bits CI lire dans le
bool HasNext(
texte.
Ecriture d'une
chaine de caractere bit
el
bit
De la me me fac;on qu il faut pouvoir lire une chalne de caractere bit CI bit 9vant de la coder , il faut
egalement pouvoir ecrire une chaine de caractere bit a bit une fois le codage effectue. Pour cela
vous allez ecrire
une classe.(.(
TBitStringWrite
La classe
TBitStringWrite))
devra posseder une
donnee membre de type .(( chalne )) contenant le texte dejCi code.
12. Ecrire une methode void WriteBit(int bit)))
permettant d' ajouter un bit Ci
la fin
de la
chalne de caractere.
13. Ecrire une methode.(.(
ToString))
permettant d' obtenir le texte dejCl code.
Codage de Huffman
Dans cette partie nous allons ecrire un
ensemble de methodes permettant d' effectuer
le codage de
Huffman CI proprement parler.
14. Ecrire une methode ou operateur .(-(int ( ))) renvoyant un tableau de 256 cases contenant
le nombre d' occurrences de chaque caractere dont le code ASCIr est compris entre 0 et
255 dans le texte parametre (le nombre d' occurrences
stocke dans la i- eme case du tableau renvoye).
du caractere de code
Asar 1 est
15. Etant donne une liste de caracteres avec leurs occurrences , on construit un arbre binaire
appele
.(-(arbre de Huffman)) permettant de coder ce texte , en appiiquant j; aigorithme
suivant:
une liste de caracteres avec leurs occurrences.
RESULTAT:
une liste de caracteres avec leurs occurrences.
ALGORITHME:
Supprimer de la liste des caracteres tous les caracteres dont le nombre
occurrences est nulle.
DONNEES
Remplacer chaque caractere par un arbre
ayant un seul nreud contenant ce
caractere et dont le poids est egal au nombre d' occurrences
correspondant.
du caractere
Tant que la liste des arbres contient au moins deux elements .
Trier la liste des arbres.
Remplacer les deux premiers arbres de la liste par un nouvel arbre tel que
le premier element de la liste soit le descendant droit de la racine. Le
3/5
-.-----------------.---- -------
poids de ce nouvel arbre est par definition
------.
-- .-.
la somme des poids des deux
arbres utilises dans sa construction.
Le resultat est le seul arbre restant dans la liste.
Ecrire une methode de la classe.(.( T
)) renvoyant un
)) construit en appliquant cet algorithme.
((TNoeudBinaire
ArbeDeHuffman
16. Etant donne un arbre de Huffman , on associe Ci chaque feuille de l' arbre un nombre
binaire appele code de Huffman. Pour cela on applique l' algorithme suivant:
un nreud binaire n
DONNEES.
: un tableau d' entiers contenant le code de Huffman du nreud binaire n.
ALGORITHME:
Creer un tableau d' entiers dont la tai lie est la profondeur du nreud
Creer une nouvelle variable temporaire egale Ci n
Creer une variable entiere i initialisees Ci la profondeur de n Tant que temporaire n est pas la racine
RESULTAT
Si temporaire est le descendant gauche de son parent alors stocker
dans la i- eme case de code.
Sinon stocker 0 dans la i- eme case de code
Reti rer 1 Ci i.
Remplacer temporaire par son parent.
Renvoyer le tab leau code.
Ecrire une methode 0(
CodeDeHuffman(TNoeudBinaire)
)) renvoyant le code de Huffman du
nreud parametre.
Exemple :
I occurence
Caractere
12
III
J 100
Arbre de Hufan
17 Pour coder un texte
Il or
Code de Hufman
il suffit maintenant d' appliquer l' algorithme suivant:
Compter les occurrences des caracteres dans le texte
Construire l' arbre de Huffman correspondant
4/5
En utilisant la classe ((
TBitStringWrite))
ecrire un nouveau texte dans
lequel le
code binaire de chaque caractere est remplace par son code d Huffman
Ecrire une methode String Compression( String)
)) realisant cet algorithme.
18. Pour decompresser un texte il faut imperativement disposer de l' arbre de Huffman ayant
servi pour le codage. Dans la suite on supposera que cet arbre
est un
parametre de la
methode. En general il faut reconstituer cet arbre CI partir des occurrences des
caracteres dans le texte non compresse lesquels doivent etre enregistres au debut
du
texte compresse.
DONNEES:
une chal'ne contenant un texte code
arbre de Huffman ayant servi CI coder le texte
RESULTAT:
Le texte decompresse
ALGORITHME:
Creer une nouvelle chal'ne resultat destine Ci recevoir le resultat.
Cr.eer une nouvelle variable temporaire de type TNoeudBinaire
)) faisant
reference a Huffman
il reste des bits non lus dans le texte
Lire le prochain bit
Tant qu
Si ce bit est nul alors remplacer.(.(
temporaire))
sinon le remplacer par temporaire- )droite
Si temporaire))
est une feuille de l' arbre
par.(.(
temporaire- )o9auche
qui le contient alors ajouter son
contenu Ci la fin de resultat et remplacer la reference contenue dans la
variable temporaire))
par une reference vers Huffman.
Renvoyer resultat transforme
19. Ecrire une deuxieme version de compression et dec.ompression afin d' enregistrer les
occurrences des caracteres et ainsi de ne pas avoir besoin de l' arbre de Huffman en
parametre de la methode de compression.
.20. Ecrire des methodes permettant de compresser et decompresser des fichiers.
NOTAS :
Les questions sont independantes et peuvent etre traite es non sequentiellement
Vous etre libre de l' implementation du code tout en respectant la philosophie objet.
Vous etes libre d'ajouter toute propriete aux classes que vous jugez utile.
5/5
Téléchargement