Exercices

July 28, 2017 | Author: ossama | Category: Markup Language, Xml, Graph Theory, Technology, Computing
Share Embed Donate


Short Description

Download Exercices...

Description

Questions d'examens de Structures de données ainsi que leurs corrigés

Questions d'examens de Structures de données ainsi que leurs corrigés Contrôle continu du 7 mai 2001 (notes) ●

Arbre lexicographique



Arbre de tri

Examen écrit du 4 octobre 2000 (notes) ●

Arbres + chaînes



Les listes



Les B-arbres

Examen écrit du 3 juillet 2000 (notes) ●

Conversion arbre-chaîne



Arbres multiples



Listes



Graphes orientés

Contrôle continu du 22 juin 2000 (notes) ●

Fermeture transitive



Graphe orienté



parcours d'un B-arbre

Contrôle continu du 11 mai 2000 (notes) ●

Chaînes



Chaînes



Arbre de tri

http://cuisung.unige.ch/std/questions.html (1 of 5) [23-09-2001 15:57:36]

Questions d'examens de Structures de données ainsi que leurs corrigés

Examen écrit du 28 février 2000 ●

Structures statiques



Anneaux bidirectionnels



Arbres dépliables



B-arbres

Examen écrit du 11 octobre 1999 ●

Anneaux bidirectionnels



Arbres



Listes



Chemin le plus court dans un graphe

Examen écrit du 30 juin 1999 (notes) ●

Anneaux bidirectionnels



Arbres dépliables



Le chemin le plus court



Hash-Coding

Contrôle continu du 14 juin 1999 (notes) ●

Graphes orientés



B-Arbres



Adressage associatif par transformation de clés (Hash-code)

Contrôle continu du 29 avril 1999 (notes) ●

Chaînes bidirectionelles



Arbre lexicographique

Examen écrit de février 1999 ●

http://cuisung.unige.ch/std/questions.html (2 of 5) [23-09-2001 15:57:36]

Questions d'examens de Structures de données ainsi que leurs corrigés

Examen écrit du 7 octobre 1998 ●

Arbre binaire Structures de graphes orientés (tri topologique inverse)



comparaison de B-arbres et B*-arbres



Hash-coding



Examen écrit du 25 juin 1998 ●

Arbres dépliables



Recherche dichotomique Hash-coding Tables de décision

● ●

Contrôle continu du 15 juin 1998 ●

Fichiers séquentiels indexés



Recherche dans un B-arbre



Le chemin du moindre coût

Contrôle continu du 4 mai 1998 ●

Chaînes bidirectionnelles



Chaînes mono-directionnelles



Anneaux bidirectionnels



Arbre syntaxique

Examen écrit de février 1998 ● ●

arbre dépliable de tri Fichiers séquentiels indexés

Examen écrit du 13 octobre 1997 ●

Structures de graphes



un réseau de transport

http://cuisung.unige.ch/std/questions.html (3 of 5) [23-09-2001 15:57:36]

Questions d'examens de Structures de données ainsi que leurs corrigés

Examen écrit de juillet 1997 ● ● ●

Arbres binaires Graphe orienté B-arbre

Contrôle continu du 16 juin 1997 ●

Arbre lexicographique



Hash-code



Tables de décision

Contrôle continu du 28 avril 1997 ●

Chaînes bidirectionnelles



Chaînes bidirectionnelles



Arbre généalogique

Examen écrit du 5 mars 1997 ●

Tri dans une chaîne Arbres syntaxiques et chaînes



B-arbre



Examen écrit du 15 octobre 1996 ●

Chaînes bidirectionnelles



Fichiers séquentiels indexés et B-arbres

Examen écrit du 9 juillet 1996 ●

Chaînes mono-directionnelles



Réseau autoroutier

http://cuisung.unige.ch/std/questions.html (4 of 5) [23-09-2001 15:57:36]

Questions d'examens de Structures de données ainsi que leurs corrigés

Contrôle continu du 17 juin 1996 ●

Anneaux bidirectionnels



Arbre de tri



Tri topologique inverse



B-arbre

Contrôle continu de mars 1996 ●

Structure de chaîne

Contrôle continu du 20 juin 1995 ●

Chaînes bidirectionnelles



Arbre lexicographique



Plus courts chemins dans un graphe

http://cuisung.unige.ch/std/questions.html (5 of 5) [23-09-2001 15:57:36]

Description du cours "Structures de donnees"

TITRE: STRUCTURES DE DONNEES Enseignant: Bertrand Ibrahim (MER) No: 1803

Heures totales: 84

Destinataire licence informatique diplôme informatique certificat . info et stat. dipl. math.info.

Par semaine: Cours: 4 Exercices: 2

Semestre 2 2 2 4

Oblig.

Facult.

Option

Pratique: Crédits 10 10 10

Objectifs Ce cours a pour but d'introduire un panorama des structures de données complexes en suivant l'approche de la programmation procédurale.

Contenu Note: un calendrier d'avancement dans le cours est disponible pour vous permettre de déterminer ce qui a été abordé à chaque leçon. ● structures de données statiques, types abstraits, notion de pointeur, ● structures dynamiques fondamentales: ❍ chaînes (monodirectionnelles, bidirectionnelles), anneaux (monodirectionnels, bidirectionnels), piles, files d'attentes, ❍ listes généralisées, ❍ arbres , ❍ graphes

● ● ●

algorithmes de construction, de parcours et de manipulation; représentations internes, opérations de base, transformation de clés et «hash-coding», structures complexes: séquentiel indexé et B-arbres, tables et arbres de décision.

Forme de l'enseignement: Cours ex-cathedra, exercices, travaux pratiques

http://cuisung.unige.ch/std/Descr.html (1 of 2) [23-09-2001 15:58:15]

Description du cours "Structures de donnees"

Evaluation: ●

Contrôles continus : ❍ lundi 7 mai 2001 de 14h00 à 16h00, auditoire U600 (Uni Dufour, 1er sous-sol) - notes jeudi 21 juin de 14h00 à 16h00, salle 259 Examen écrit, juillet Evaluation du cours par les étudiants (année 2000) ❍

● ●

Note: dans les deux formes d'évaluation des étudiants (contrôle continu ou examen écrit), la note sera laissée en suspend jusqu'à avoir satisfait aux exigences des travaux pratiques (avoir 75% des TPs acceptés par l'assistant).

Encadrement: Bertrand Ibrahim (bur. 350), Wolfgang Müller (bur. 336), Yvan Petroff (bur. 306).

Documentation: livre support de cours et liste d'ouvrages de référence. Liste des questions d'examens avec leurs corrigés. Enregistrements sonores

Liaison avec d'autres cours: Préalable requis: Algorithmique ou Introduction à l'informatique. Préparation pour: informatique théorique, initiation à la recherche opérationnelle et langages informatiques. B. Ibrahim 19.04.01

http://cuisung.unige.ch/std/Descr.html (2 of 2) [23-09-2001 15:58:15]

Notes du contrôle continu du 7 mai 2001

Structures de Données

Notes du contrôle continu du 7 mai 2001 Nom

Q1 Q2 Note

ALBUQUERQUE Michel

5

19

2,3

BAERTSCHIGER Didier

30

35

6,0

BELKABIR M??

3

0

0,3

BOUDJNANE Yassin

13

26

3,9

BRUNSCHWIG Guillaume

4

2

0,6

CABY Gerda

1

14

1,5

CHARPILLOZ Christophe

25

16

4,1

COSTANITA Rodrigue

9

23

3,2

DUCIMETIERE Jérôme

1

29

3,0

EL HASNAOUI Hassan

4

10

1,4

EMIYAN Stéphane

15

29

4,4

ETIENNE Julien

20

27

4,7

FERROUKHI Sid-Ahmed

0

13

1,3

FIRST Jean

22

33

5,5

FONTIGNIE Jacques

30

29

5,9

GULATI Asheesh

22

35

5,7

[5,5-6,0] xxxxx xxxx

JAMES Mélanie

30

35

6,0

[5,0-5,5[ xxxxx x

JOSS Olivier

30

27

5,7

[4,5-5,0[ xxxxx xx

LAGROUNI Kamal

25

24

4,9

[4,0-4,5[ xxxx

MAGPANTAY Tristan

19

29

4,8

MARQUIS Samuel

22

29

5,1

NGUYEN Duy

22

29

5,1

Répartition des notes

[3,5-4,0[ xxx [3,0-3,5[ xxxxx

http://cuisung.unige.ch/std/CC/010507/Notes.html (1 of 2) [23-09-2001 15:58:19]

[2,5-3,0[ [2,0-2,5[ x

Notes du contrôle continu du 7 mai 2001

NGUYEN Thi Anh Thu

25

12

3,7

[1,5-2,0[ xx

PINEIRO Elvis

25

22

4,7

[1,0-1,5[ xx

PORTA Jonathan

9

29

3,8

PRAPLAN Christophe

22

30

5,2

QUANG Anh

15

26

4,1

REVERDON Ludovic

4

26

3,0

RIVERA CAMACHO Ernesto A. 25

35

6,0

ROSSET Giles

27

35

6,0

SARTORETTI Fabien

25

26

5,1

SAYAH Saïd

15

26

4,1

SCHALLER Cynthia

25

28

5,3

STURB Ronald

1

14

1,5

SUHNER Thierry

12

35

4,7

STRUMIELLO Olivier

24

24

4,8

TUVERI Jairo

25

24

4,9

UMER Ali

4

26

3,0

VILLALBA Alfredo

30

35

6,0

VILLASUSO Pablo

22

29

5,1

WANG ia Ying

12

18

3,0

[0,5-1.0[ x [0-0,5[

Dernière modification: 15.06.01

http://cuisung.unige.ch/std/CC/010507/Notes.html (2 of 2) [23-09-2001 15:58:19]

x

Structuration des Données Informatiques - 8.2, exercice 5

Arbre lexicographique Question posée au contrôle continu du 7 mai 2001 On a construit un arbre multiple d'ordre 26 permettant de stocker des mots d'un dictionnaire de façon que les chemins partant de la racine représentent des mots du dictionnaire, de la façon suivante

Les arcs sont étiquettés avec les lettres de l'alphabet (on suppose ici que l'on ne tient pas compte des accents sur les lettres) et les noeuds contiennent un booléen indiquant si le chemin de la racine à ce noeud représente un mot complet ou pas (sur le dessin - = faux et * = vrai). Sur la base des déclarations suivantes, écrivez une fonction Trouve indiquant si un mot se trouve dans le dictionnaire. type VersNoeud= ^Noeud; Noeud= record Desc: array['a'..'z'] of VersNoeud; Complet: boolean; end; { Noeud } var Dico: VersNoeud; function Trouve(Mot: string; Dico: VersNoeud):boolean; Solution

http://cuisung.unige.ch/std/ex/8/2e.html [23-09-2001 15:58:24]

Structuration des Données Informatiques - 8.1, exercice 8

Arbre de tri Question posée au contrôle continu du 7 mai 2001 Complétez le code des procédures ajouteElement, sommeArbre et produitArbre. La procédure accumulerArbre est facultative et vaut un bonus de 5 points. { Ajoutez le code necessaire } program completer; type pElement TElement

= ^TElement; = record mContenu : integer; mDroite,mGauche : pTElement; end; { TElement } {un type de FONCTION} TFonction = function(x, y:integer):integer;

var gRacine: pElement; i,gSomme,gProduit, gNouveau : integer; { multiplier: Cette fonction multiplie deux nombres entiers parametres: inX, inY: les deux nombres a multiplier resultat: inX*inY } function multiplier(inX,inY:integer):integer; begin multiplier:=inX*inY; end; { multiplier } { ajouter: Cette fonction ajoute inX a inY parametres: inX, inY: les deux nombres a additionner resultat: http://cuisung.unige.ch/std/ex/8/1h.html (1 of 5) [23-09-2001 15:58:29]

Structuration des Données Informatiques - 8.1, exercice 8

inX+inY } function ajouter(inX,inY:integer):integer; begin ajouter:=inX+inY; end; { ajouter } {---------------------------------------gestion d'arbres ----------------------------------------} { creeElement_Contenu Cette fonction cree un nouveau element d'un arbre avec un contenu donné. Les pointeurs de l'element a creer vont etre mis a NIL. parametres: inNouveauContenu : le contenu de l'element a creer var outElement: le pointeur sur l'element cree } procedure creeElement_Contenu(inNouveauContenu : integer; var outElement : pElement); begin new(outElement); outElement^.mDroite:=nil; outElement^.mGauche:=nil; outElement^.mContenu:=inNouveauContenu; end; { creeElement_Contenu }

{ Ajoute un element a l'arbre pour que l'arbre soit un arbre de tri, les elements les plus petits a gauche. parametres: inNouveauContenu: le contenu de l'element a ajouter inoutRacine: la racine de l'arbre a qui un element va etre ajoute } procedure ajouteElement(inNouveauContenu:integer; var inoutRacine: pElement); begin {QUESTION: http://cuisung.unige.ch/std/ex/8/1h.html (2 of 5) [23-09-2001 15:58:29]

Structuration des Données Informatiques - 8.1, exercice 8

AJOUTEZ LE CODE NECESSAIRE POUR QUE ajouteElement FASSE CE QUI EST DIT DANS LE COMMENTAIRE. Vous n'avez pas besoin de variables supplementaires. Toutefois, on autorise l'ajout de variables LOCALES. }

end; { ajouteElement } { Cette procedure calcule la somme de tous les elements dans l'arbre et l'ajoute a inoutSomme parametres: var inoutSomme: le parametre d'entree et le resultat var inRacine: la racine de l'arbre a traiter } procedure sommeArbre(var inoutSomme:integer; var inRacine: pElement); begin {QUESTION: AJOUTEZ LE CODE NECESSAIRE POUR QUE sommeArbre FASSE CE QUI EST DIT DANS LE COMMENTAIRE. Vous n'avez pas besoin de variables supplementaires. Toutefois, on autorise l'ajout de variables LOCALES. } end; { sommeArbre } { La procedure qui suit calcule le produit de tout les elements dans l'arbre et le multiplie avec inoutProduit parametres: var inoutProduit: le parametre d'entree et le resultat var inRacine: la racine de l'arbre a traiter } procedure produitArbre(var inoutProduit:integer; var inRacine: pElement); begin {QUESTION: AJOUTEZ LE CODE NECESSAIRE POUR QUE produitArbre FASSE CE QUI EST DIT DANS LE COMMENTAIRE. } http://cuisung.unige.ch/std/ex/8/1h.html (3 of 5) [23-09-2001 15:58:29]

Structuration des Données Informatiques - 8.1, exercice 8

... end; { produitArbre } { La procedure qui suit traverse l'arbre en-ordre et applique inFonction au contenu de la racine et inoutAccumulateur dans la maniere suivante: parametres: inoutAccumulateur: contient un nombre entier apres l'appel il contient le resultat de l'appel inFonction: contient une fonction de type TFonction; inRacine: contient la racine d'un arbre de tri genere par ajouteElement Car inRacine contient un arbre de tri, les elements de l'arbre sont trie du plus petit au plus grand si on fait un parcours en-ordre: n_1 < n_2 < ... < n_m 1..m sont les numeros de visite, donc n_1 est visite avant n_2, n_3 etc. Apres un apel d'accumulerArbre avec inoutAccumulateur=i, inFonction=f, et un arbre comme parametre, inoutAccumulateur va contenir: inoutAccumulateur=f(n_m,f(...,f(n_2,f(n_1,i)))) } procedure accumulerArbre(var inoutAccumulateur : integer; inFonction : TFonction; var inRacine: pElement); begin {QUESTION FACULTATIVE: AJOUTEZ LE CODE NECESSAIRE POUR QUE accumulerArbre FASSE CE QUI EST DIT DANS LE COMMENTAIRE. Vous n'avez pas besoin de variables supplementaires. Toutefois, on autorise l'ajout des variables LOCALES. http://cuisung.unige.ch/std/ex/8/1h.html (4 of 5) [23-09-2001 15:58:29]

Structuration des Données Informatiques - 8.1, exercice 8

} ... end; { accumulerArbre } { SI TOUS LES QUESTIONS SONT BIEN RESOLUES, LE PROGRAMME DOIT AFFICHER TROIS FOIS LES MEMES gSomme ET gProduit RESPECTIVEMENT } begin gRacine:=nil; gSomme:=0; gProduit:=1; { cree arbre aleatoire de 4 elements } for i:=1 to 4 do begin gNouveau:=random(10)+1; ajouteElement(gNouveau, gRacine); gSomme:= gSomme + gNouveau; gProduit:= gProduit * gNouveau; end; { for } write('gSomme:'); writeln(gSomme); write('gProduit:'); writeln(gProduit); gSomme:= 0; gProduit:= 1; sommeArbre(gSomme, gRacine); produitArbre(gProduit, gRacine); write('gSomme:'); writeln(gSomme); write('gProduit:'); writeln(gProduit); gSomme:= 0; gProduit:= 1; accumulerArbre(gSomme, ajouter, gRacine); accumulerArbre(gProduit, multiplier, gRacine); write('gSomme:'); writeln(gSomme); write('gProduit:'); writeln(gProduit); end. Solution

http://cuisung.unige.ch/std/ex/8/1h.html (5 of 5) [23-09-2001 15:58:29]

Notes du contrôle continu du 22 juin 2000

Structures de Données

Notes de l'examen du 4 octobre 2000 Nom

Q1 Q2 Q3

Note

Albuquerque Paul Bajrami Gent

Répartition des notes absent

5

12

11

3,0

Ben Hadj Noureddine

[5,5-6,0] [5,0-5,5[

absent

[4,5-5,0[ [4,0-4,5[

Benkacem Omar

5

20

13

en attente des TPs

Benouataf Khalil

0

0

9

1,0

Coron Olivier

10

30

13

5,5

Londo Ilia

5

18

5

en attente des TPs

[2,0-2,5[

Maddi Brahim

3

6

3

1,0

[1,5-2,0[

Nguyen Thi Amh Thu 4

8

7

2,0

[1,0-1,5[

Schaller Cynthia

1

11

2,0

8

Dernière modification: 27.10.00

http://cuisung.unige.ch/std/Exa/Notes001004.html [23-09-2001 15:58:32]

x

x

[3,5-4,0[ [3,0-3,5[

xx

[2,5-3,0[

[0,0-1,0[

xx xx

Structuration des Données Informatiques - 8.1, exercice 7

Exercice suivant

Arbres + chaînes Question posée à l'examen écrit du 4 octobre 2000 Soit une structure d'arbre de tri et une structure de chaîne bidirectionnelle représentées par les déclarations suivantes: type pNoeudArbre = ^NoeudArbre; NoeudArbre = record nombre: integer; gauche, droite: pNoeudArbre; end; { NoeudArbre } PtrNoeudCh = ^NoeudCh; NoeudCh = record Element: pNoeudArbre; Precedent, Suivant: PtrNoeudCh; end; { NoeudCh } Ecrivez une fonction "Chemin" qui prend en paramètre un arbre et une valeur et retourne en résultat une chaîne pointant sur les éléments successifs de l'arbre qui auront été examinés pour trouver la valeur dans l'arbre de tri: function Chemin(MonArbre: pNoeudArbre; MaValeur: integer): PtrNoeudCh; Il faut bien entendu traiter tous les cas particuliers, p.ex. si l'arbre est vide la chaîne sera vide, si la valeur fournie n'existe pas dans l'arbre, il faudra retourner le chemin parcouru jusqu'à trouver que la valeur ne se trouve pas dans l'arbre. Solution Exercice suivant

http://cuisung.unige.ch/std/ex/8/1g.html [23-09-2001 15:58:34]

Structuration des Données Informatiques - 9.1, exercice 3

Listes Question posée à l'examen du 4 octobre 2000 { Voici un programme qui gère les listes à la façon de Scheme } program liste_scheme; type PPaireOuValeur = ^TPaireOuValeur; TPaireOuValeur = record mEstValeur : boolean; mValeur : integer; mPremier : PPaireOuValeur; mDeuxieme : PPaireOuValeur; end; var i : integer; gChaine : PPaireOuValeur; function cons_paire_paire(inPremier, inSecond: PPaireOuValeur) : PPaireOuValeur; var lResultat: PPaireOuValeur; begin new(lResultat); lResultat^.mEstValeur:=false; lResultat^.mPremier:= inPremier; lResultat^.mDeuxieme := inSecond; cons_paire_paire:=lResultat; end; { cons_paire_paire } function cons_integer_paire(inPremier: integer; inSecond: PPaireOuValeur): PPaireOuValeur; var lInteger: PPaireOuValeur; begin new(lInteger); lInteger^.mEstValeur:=true; lInteger^.mValeur:=inPremier; cons_integer_paire:=cons_paire_paire(lInteger,inSecond); end; { cons_integer_paire } function cons_integer_integer(inPremier : integer; inSecond: integer): PPaireOuValeur;

http://cuisung.unige.ch/std/ex/9/1c.html (1 of 3) [23-09-2001 15:58:37]

Structuration des Données Informatiques - 9.1, exercice 3

var lInteger : PPaireOuValeur; lPaire : PPaireOuValeur; begin new(lInteger); lInteger^.mEstValeur:=true; lInteger^.mValeur:=inSecond; cons_integer_integer:=cons_integer_paire(inPremier,lInteger); end; { cons_integer_integer } { QUESTION: Ecrivez une fonction qui crée une liste à la façon de Scheme avec les entiers dans l'intervalle de inBegin à inEnd. cree_chaine(5,8) devrait retourner l'equivalent de (list 5 6 7 8). cree_chaine(5,5) devrait retourner l'equivalent de (list 5), cree_chaine(5,4) devrait donner nil comme resultat. } function cree_chaine(inBegin,inEnd : integer ):PPaireOuValeur; var lLastCreated: PPaireOuValeur; var i: integer; begin { } end; { QUESTION: Créez une procedure qui parcourt et affiche des chaînes simples à la Scheme de façon à donner p.ex. pour affiche_chaine(cree_chaine(5,7)) la procédure affiche "(5 6 7)" à l'écran La procedure peut être limitée aux chaines simples (pas de listes imbriquées, donc p.ex. "(list 1 2 3 4)" mais pas "(cons (list 1 2) (list 3 4))") } procedure affiche(inPaireOuValeur: PPaireOuValeur); var lCourant: PPaireOuValeur; begin { http://cuisung.unige.ch/std/ex/9/1c.html (2 of 3) [23-09-2001 15:58:37]

Structuration des Données Informatiques - 9.1, exercice 3

} end; { affiche } begin gChaine:=cree_chaine(1,10); writeln('Chaine cree'); affiche(gChaine); affiche(cree_chaine(5,8)); affiche(cons_paire_paire(cree_chaine(1,2), cons_integer_integer(3,4))); end. Solution

http://cuisung.unige.ch/std/ex/9/1c.html (3 of 3) [23-09-2001 15:58:37]

Structuration des Données Informatiques - 14.3, exercice 8

Les B-Arbres Question posée à l'examen du 4 octobre 2000 . Soit le B-arbre d'ordre 2 suivant, dessinez le B-arbre résultant de l'insertion de la valeur 25:

b. Avec le même B-arbre de départ qu'en (a), dessinez le B-arbre résultant de l'insertion de la valeur 20 c. Avec le même B-arbre de départ qu'en (a), dessinez le B-arbre résultant de l'insertion de la valeur 14 d. Avec le même B-arbre de départ qu'en (a), dessinez le B-arbre résultant de l'insertion de la valeur 6 e. Avec le même B-arbre de départ qu'en (a), dessinez le B-arbre résultant de la suppression de la valeur 60 f. Avec le même B-arbre de départ qu'en (a), dessinez le B-arbre résultant de la suppression de la valeur 63 g. Avec le même B-arbre de départ qu'en (a), dessinez le B-arbre résultant de la suppression de la valeur 80 Solution

http://cuisung.unige.ch/std/ex/14/3h.html [23-09-2001 15:58:43]

Notes du contrôle continu du 22 juin 2000

Structures de Données

Notes de l'examen du 3 juillet 2000 Nom

Q1 Q2 Q3 Q4 Note

Bajrami Gent

6

15

2

0

2,5

Ben Hadj Noureddine

2

8

0

0

1,0

Benkacem Omar

5

6

5

0

1,5

[5,5-6,0]

Benouataf Khalil

0

11

0

0

1,0

[5,0-5,5[

Bobo Ngawouo Aimé Patrick 0

1

2

0

0,5

[4,5-5,0[

x

Braik Ahcene

10

15

0

4

3,0

[4,0-4,5[

xx

Buhler Stéphane

10

13

10

7

4,0

Coron Olivier

8

13

5

2

3,0

Etienne Julien

12

13

11

9

Habachi Arash

6

4

15

Maddi Brahim

3

6

Nguyen Thi Amh Thu

1

Petrini Geo Schaller Cynthia

Répartition des notes

[3,5-4,0[ [3,0-3,5[

xx

[2,5-3,0[

xxx

4,5

[2,0-2,5[

x

13

4,0

[1,5-2,0[

x

2

0

1,0

[1,0-1,5[

xxx

12

0

0

2,5

[0,0-1,0[

x

12

0

13

0

2,5

6

12

0

0

2,0

Dernière modification: 21.07.00

http://cuisung.unige.ch/std/Exa/Notes000703.html [23-09-2001 15:58:48]

Structuration des Données Informatiques - 8.1, exercice 6

Exercice suivant

Conversion arbre-chaîne Question posée à l'examen écrit du 3 juillet 2000 Soit une structure d'arbre de tri et une structure de chaîne bidirectionnelle représentées par les déclarations suivantes: type pNoeudArbre = ^NoeudArbre; NoeudArbre = record nombre: integer; gauche, droite: pNoeudArbre; end; { tNoeudArbre } PtrNoeudCh = ^NoeudCh; NoeudCh = record Donnee: integer; Precedent, Suivant: PtrNoeudCh; end; Ecrivez une fonction "Conversion" qui prend en paramêtre un arbre et retourne en résultat une chaîne contenant les valeurs de l'arbre dans l'ordre croissant. Solution Exercice suivant

http://cuisung.unige.ch/std/ex/8/1f.html [23-09-2001 15:58:54]

Structuration des Données Informatiques - 8.2, exercice 4

Exercice suivant

Arbre multiple Question posée à l'examen écrit du 3 juillet 2000 Le langage XML est un langage de balises destiné à succéder au langage HTML. En simplifiant, on peut dire qu'un document XML contient un élément racine. Cet élément racine est un élément complexe, c'est-à-dire qu'il contient un ou plusieurs autres éléments. Chaque élément est soit du texte simple, soit un élément vide composé uniquement d'une balise de la forme "", soit un élément complexe délimité, à son début, par une balise d'ouverture de la forme "", à sa fin, par une balise de fermeture de la forme "" et contenant, entre deux, une succession d'éléments. Un document XML peut être vu comme une structure arborescente du type arbre multiple. En supposant que Y est représenté par

en appliquant cette représentation récursivement et et en tenant compte des différentes possibilités de représenter des arbres multiples, dessinez deux représentations arborescentes différentes pour le document suivant: Un journaliste accuse, un policier dément Alain Connu 14 juin 1972 banquise Un journaliste de la place accuse les autorités ... Solution Exercice suivant

http://cuisung.unige.ch/std/ex/8/2d.html [23-09-2001 15:58:58]

Structuration des Données Informatiques - 9.1, exercice 2

Exercice suivant

Listes Question posée à l'examen du 3 juillet 2000 program SchemeList; { une structure qui peut contenir soit une valeur, soit une paire } type PSchemePaireOuValeur = ^TSchemePaireOuValeur; TSchemePaireOuValeur = record { le record contient-il une valeur } mEstValeur:boolean; {si ce record est une valeur} mValeur : integer; {si ce record est une paire} { car de la paire} mCar : PSchemePaireOuValeur; { cdr de la paire } mCdr : PSchemePaireOuValeur; end; { TSchemePaireOuValeur } var gSchemePaire: PSchemePaireOuValeur; { Une fonction qui cree une valeur } function creeValeur(inValeur : integer): PSchemePaireOuValeur; var lResultat : PSchemePaireOuValeur; begin new(lResultat); lResultat^.mEstValeur:=true; lResultat^.mValeur:=inValeur; lResultat^.mCar:=nil; lResultat^.mCdr:=nil; creeValeur:=lResultat; end; { creeValeur } { Une fonction qui cree une paire } function creePaire(inCar,inCdr: PSchemePaireOuValeur):PSchemePaireOuValeur; var lResultat : PSchemePaireOuValeur; begin new(lResultat); lResultat^.mEstValeur:=false;

http://cuisung.unige.ch/std/ex/9/1b.html (1 of 2) [23-09-2001 15:59:01]

Structuration des Données Informatiques - 9.1, exercice 2

lResultat^.mValeur:=0; lResultat^.mCar:=inCar; lResultat^.mCdr:=inCdr; creePaire:=lResultat; end; { creePaire } { Une procedure pour afficher } procedure display(inPaire : PSchemePaireOuValeur); {vous etes autorise(es) de mettre des variables ici} begin {Mettez votre code ici. Les commentaires du programme principal vous indiquent ce que la procedure Display est censee imprimer} end; begin gSchemePaire:=creePaire(creeValeur(1), creePaire(creeValeur(2), creePaire(creeValeur(3),nil))); display(nil) {donne "()"}; writeln; display(gSchemePaire); {donne "(1 . (2 . (3 . ())))"} gSchemePaire:=creePaire(creePaire(creeValeur(1), creeValeur(2)), creePaire(creeValeur(3), creeValeur(4))); writeln; display(gSchemePaire); {donne "((1.2).(3.4))"} end. Solution Exercice suivant

http://cuisung.unige.ch/std/ex/9/1b.html (2 of 2) [23-09-2001 15:59:01]

Structuration des Données Informatiques - 11. exercice 4

Graphe orienté Question posée à l'examen écrit du 3 juillet 2000 L'on modélise un planning à l'aide des structures suivantes : var Debut: array [1..NbTaches] of Integer; { pour chaque tâche, le jour auquel elle est censée débuter } Duree: array [1..NbTaches] of Integer; { la durée de chaque tâche, en nombre de jours } Avant: array [1..NbTaches,1..NbTaches] of Boolean; { Avant[X,Y] vrai si la tâche X doit être achevée avant le début de Y } Écrire une procédure/fonction étudiant la cohérence de ces données, c.-à-d. : 1. vérifier que chaque tâche peut bien commencer au jour prévu, en tenant compte de la durée de ses antécédentes; 2. si cela n'est pas vérifié, imprimer où se situe l'erreur, et quel est l'enchaînement des tâches précédentes (depuis l'origine) à prendre en compte pour déterminer la date de début correcte ; 3. le cas échéant, proposer des améliorations locales du planning (quand une tâche pourrait commencer plus tôt que prévu). Il n'est pas demandé de modifier les données initiales, ni de réaliser plusieurs passes, chacune tenant compte des corrections ( avancée ou retardement d'une tâche) de la précédente. Toutefois, s'il vous reste du temps, cela pourra constituer un bonus... Attention : il n'est pas spécifié que les tâches doivent s'effectuer l'une après l'autre, certaines peuvent s'accomplir en parallèle. De même, la racine du processus n'est pas nécessairement unique (ni le graphe connexe). NB: Les variables Debut, Duree et Avant sont globales, et peuvent être utilisées comme telles dans votre code. Solution

http://cuisung.unige.ch/std/ex/11/d.html [23-09-2001 15:59:04]

Notes du contrôle continu du 22 juin 2000

Structures de Données

Notes du contrôle continu du 22 juin 2000 Nom

Q1 Q2 Q3 Note

ARRIS Latifa

5

7

5

1,7

BLANC Jérémy

17

18

20

5,5

BOUGET M.

20

20

20

6,0

Répartition des notes

COLA Stéphane

17

11

17

4,5

[5,5-6,0]

xxxxxx

GEROME-BAUQUIS Isis 16

6

8

3,0

[5,0-5,5[

x

HAENGGELI Christophe

17

18

20

5,5

[4,5-5,0[

xxx

HEUBERGER Joris

17

20

19

5,6

HYSI Hilda

17

10

10

3,7

JABRI Abdelmajid

15

2

8

LOGEAY Camille

17

15

POSKRIAKOV Sergei

17

RAY Nicolas

[4,0-4,5[ [3,5-4,0[

x

[3,0-3,5[

xx

2,5

[2,5-3,0[

x

13

4,5

[2,0-2,5[

20

16

5,3

[1,5-2,0[

17

17

11

4,5

[1,0-1,5[

RENQUIN Johan

18

18

20

5,6

SARAZIN Benoît

17

7

8

3,2

YAPY Luis

20

18

14

5,2

Dernière modification: 19.07.00

http://cuisung.unige.ch/std/CC/000622/Notes.html [23-09-2001 15:59:06]

x

Structuration des Données Informatiques - 11.3, exercice 4

Graphes orientés Question posée au contrôle continu du 22 juin 2000 Dessinez la fermeture transitive de chacun de ces quatre graphes:

Solution

http://cuisung.unige.ch/std/ex/11/3d.html [23-09-2001 15:59:13]

Structuration des Données Informatiques - 11. exercice 3

Exercice suivant

Graphe orienté Question posée au contrôle continu du 22 juin 2000 Il est aisément démontrable que lorsque l'on élève un nombre N au carré, les deux derniers chiffres du résultat ne dépendent que des deux derniers chiffres de N. Ainsi, un nombre se terminant par 05 aura toujours son carré se terminant par 25 ( 105->11025, 1905->3629025 ). L'on peut donc définir une application reliant chacun des nombres de 00 à 99 à un autre de ces nombres, correspondant à la valeur de son carré modulo 100. Ceci compose bien entendu un graphe orienté... 1. Considérant que chacun des noeuds est l'origine d'un et un seul arc, déterminez la structure de données la plus simple adaptée à la représentation des arcs de ce graphe. La propriété précédente amène logiquement ceci : puisqu'un noeud a au plus un successeur (en fait, exactement un), l'on peut définir en suivant les arcs (c'est-à-dire en réitérant le calcul) un chemin unique qui en est issu; puisque tous les noeuds ont au moins un successeur, ce chemin aboutit obligatoirement à un cycle (le nombre de noeuds étant limité). L'on aimerait donc associer à chaque noeud la "séquence terminale" (cycle) qui lui correspond. 2. Écrivez une fonction imprimant, pour un noeud passé en paramètre, les noeuds composant le cycle terminal qui lui est associé. Pensez que chaque composante du graphe ne comporte qu'un seul cycle; rappelez-vous qu'un cycle est un cas particulier de composante fortement connexe... Solution Exercice suivant

http://cuisung.unige.ch/std/ex/11/c.html [23-09-2001 15:59:16]

Structuration des Données Informatiques - 14.3, exercice 6

Exercice suivant

B-Arbres Question posée au contrôle continu du 22 juin 2000 Complétez les procédures pour parcourir des B-arbres. NB: Ces procédures sont sensées marcher avec tous les B-arbres possibles! Une solutions qui marche juste avec l'arbre donné dans ce programme n'est pas considérée comme réponse à cette question (0 points). Sont marquées en caractères gras les parties du code qui sont essentielles à l'élaboration de la solution. program b_arbre; const cTaillePage= ...; type PPage = ^TPage; { un element d'une page de b-arbre} TPageElement = record mCle : integer; { Cle } mEnfant : PPage; { Pointeur } end; { une page du b-arbre TPage = record mPremierEnfant mNombreElements mElements end;

= un noeud du b-arbre

}

: PPage;{ Le premier Enfant } : integer; : array[1..cTaillePage] of TPageElement;

var gArbre : PPage; gAuxiliaire : PPage; gTest : boolean; { Initialiser un element de page } procedure initialisePageElement(var outInitialise : TPageElement); begin outInitialise.mCle:=0; outInitialise.mEnfant:=nil; end; { Creer une page vide

http://cuisung.unige.ch/std/ex/14/3f.html (1 of 4) [23-09-2001 15:59:20]

Structuration des Données Informatiques - 14.3, exercice 6

parameter: outNouveauNoeud, la variable qui va contenir la nouvelle page } procedure creePage(var outNouveauNoeud : PPage); var i : integer; begin { creePage } new(outNouveauNoeud); outNouveauNoeud^.mPremierEnfant:=nil; outNouveauNoeud^.mNombreElements:=0; for i:=1 to cTaillePage do initialisePageElement(outNouveauNoeud^.mElements[i]); end; { creePage } { Ajoute une cle a une page existante parametres: inCle : la nouvelle Cle inoutPage : la page a modifier valeur de resultat: true, si la page n'etait pas encore pleine false, si la page etait pleine } function ajouteCleAPage(var inoutPage: TPage; inCle:integer) :boolean; begin if (inoutPage.mNombreElements'); P := P^.s2; until P = nil; else writeln('nil'); end. où la procédure initialise(var Depart:Ptr); est utilisée pour faire les initialisations: créer la chaine et initialiser le pointeur S2 à nil. Quel résultat sera affiché quand LaChaine pointe sur: 1. 2 -> 0 -> 1 -> 1 -> -3 2. 3 -> -1 -> 2 -> -1 -> -3 Solution Exercice suivant

http://cuisung.unige.ch/std/ex/7/4e.html (2 of 2) [23-09-2001 16:02:39]

Structuration des Données Informatiques - 8.2, exercice 2

Exercice suivant

Arbre généalogique Question posée au contrôle continu du 28 avril 1997 program arbre_genealogique; const MaxLongueurNom = 30; type Genre = (Masculin, Feminin); Noms = array[1..MaxLongueurNom] of char; ChaineFreresSoeurs = ^NoeudFrereSoeur; PersonnePtr = ^Personne; NoeudFrereSoeur = record FrereOuSoeur: PersonnePtr; FrereSoeurSuivant: ChaineFreresSoeurs; end; {NoeudFrereSoeur} Personne = record Nom: Noms; Prenom: Noms; Sexe: Genre; Epoux: PersonnePtr; FreresEtSoeurs: ChaineFreresSoeurs; Enfants: ChaineFreresSoeurs; end; {Personne} function NouvellePersonne(SonNom, SonPrenom: Noms; SonSexe: Genre): PersonnePtr; var laPersonne: PersonnePtr; begin new(laPersonne); with laPersonne^ do begin Nom := SonNom; Prenom := SonPrenom; Sexe := SonSexe; Epoux := nil; FreresEtSoeurs := nil; end; {with} NouvellePersonne := laPersonne; end; {NouvellePersonne}

http://cuisung.unige.ch/std/ex/8/2b.html (1 of 2) [23-09-2001 16:02:41]

Structuration des Données Informatiques - 8.2, exercice 2

procedure Epouse(epoux1, epoux2: PersonnePtr); begin epoux1^.Epoux := epoux2; epoux2^.Epoux := epoux1; end; {Epoux} procedure AjouteEnfant(Parent, Enfant: PersonnePtr); var NouveauNoeud, EnfantCourant, EnfantPrecedent: ChaineFreresSoeurs; begin new(NouveauNoeud); with NouveauNoeud^ do begin FrereOuSoeur := Enfant; FrereSoeurSuivant := nil; end; {with} EnfantCourant := Parent^.Enfants; if EnfantCourant = nil then begin {Ce nouvel Enfant est leur premier Enfant} Parent^.Enfants := NouveauNoeud; if Parent^.Epoux nil then Parent^.Epoux^.Enfants := NouveauNoeud; Enfant^.FreresEtSoeurs := NouveauNoeud; end {if} else begin Enfant^.FreresEtSoeurs := EnfantCourant; {cherche le dernier Enfant} while EnfantCourant nil do begin EnfantPrecedent := EnfantCourant; EnfantCourant := EnfantCourant^.FrereSoeurSuivant; end; {while} EnfantPrecedent^.FrereSoeurSuivant := NouveauNoeud; end; {else} end; {AjouteEnfant} Sur la base des déclarations et procédures ci-dessus, qui permettent de construire un arbre généalogique: 1. dessinez un diagramme qui montre l'utilisation de cette structure pour une famille contennant au moins deux generations; 2. écrivez une procédure qui trouvera tous les petits-enfants d'une personne et imprimera leurs noms et prénoms: procedure ImprimePetitsEnfants(LaPersonne: PersonnePtr); Solution Exercice suivant

http://cuisung.unige.ch/std/ex/8/2b.html (2 of 2) [23-09-2001 16:02:41]

Structuration des Données Informatiques - 8.1, exercice 2

Exercice suivant

Arbre syntaxique et chaîne Question posée à l'écrit du 5 mars 1997 Soit un arbre syntaxique contenant une expression arithmétique, basé sur les déclarations suivantes: type Contenus = (Operande, Operateur); Operations=(Addition, Soustraction, Multiplication, Division); VersNoeud = ^Noeud; Noeud = record case Contenu: Contenus of Operande: (Valeur: integer); Operateur:(Operation: Operations; Gauche,Droite: VersNoeud); end; (* Noeud *) Ecrivez une procédure qui convertira un tel arbre syntaxique en une chaîne contenant la même expression arithmétique en notation polonaise postfixée. Vous utiliserez à cet effet les déclarations suivantes: type VersMaillon = ^Maillon; Maillon = record Suivant: VersMaillon; case Contenu: Contenus of Operande: (Valeur: integer); Operateur:(Operation: Operations); end; (* Maillon *) Pour rappel, la notation polonaise postfixée consiste à noter une expression arithmétique avec l'opérateur à la suite des opérandes sur lesquels il porte. Cette notation ne nécessite donc pas de parenthèses. Par exemple, l'expression (85 - 9) * ((78 + 45) / (6 - 2)) est notée, en notation polonaise postfixée, de la façon suivante: 85 9 - 78 45 + 6 2 - / *. Pour vous aider, sachez que cette conversion correspond à une des méthodes classiques de parcours d'arbre. Solution Exercice suivant

http://cuisung.unige.ch/std/ex/8/1b.html [23-09-2001 16:02:44]

Structuration des Données Informatiques - 14.3, exercice 2

Exercice suivant

B-arbre Question posée à l'écrit du 5 mars 1997 a) Soit le B-arbre d'ordre 2 suivant, dessinez le B-arbre résultant de l'insertion de la valeur 10

b) Soit le B-arbre d'ordre 2 suivant, dessinez le B-arbre résultant de l'insertion de la valeur 21

c) Avec le même B-arbre de départ qu'au point b, dessinez le B-arbre résultant de la suppression de la valeur 55. d) Soit le B-arbre d'ordre 2 suivant, dessinez le B-arbre résultant de l'insertion de la valeur 23

e) Avec le même B-arbre de départ qu'au point d, dessinez le B-arbre résultant de l'insertion de la valeur 4. f) Avec le même B-arbre de départ qu'au point d, dessinez le B-arbre résultant de la suppression de la valeur 15. Solution Exercice suivant

http://cuisung.unige.ch/std/ex/14/3b.html [23-09-2001 16:02:58]

Structuration des Données Informatiques - 7.4, exercice 3

Exercice suivant

Chaînes bidirectionnelles Question posée à l'examen écrit du 15 octobre 1996 Supposons qu'un programme d'édition de texte utilise la structure de chaîne de strings suivante pour représenter le texte en cours d'édition: type VersLigne = ^UneLigne; UneLigne = record Texte: string; LignePrecedente, LigneSuivante: VersLigne; end; { UneLigne } var LeTexte: VersLigne; a) Ecrivez une procédure "EffaceLigne", selon la déclaration suivante, qui change la structure de donnée pour refléter la suppression d'une ligne du texte: procedure EffaceLigne(var UnTexte: VersLigne; NumeroLigne: integer); b) Ecrivez une procédure "JoindreLignes", selon la déclaration suivante, qui change la structure de donnée pour combiner la ligne courante et la ligne suivante en une seule ligne (le contenu de la ligne suivante est inséré à la fin de la ligne courante et la ligne suivante est alors supprimée): procedure JoindreLignes(var UnTexte: VersLigne; LigneCourante: integer); Dans les deux cas, il faudra prendre soin de vérifier tous les cas particuliers et diagnostiquer toutes les erreurs éventuelles. Solution Exercice suivant

http://cuisung.unige.ch/std/ex/7/4c.html [23-09-2001 16:03:00]

Structuration des Données Informatiques - 14.2, exercice 1

Exercice suivant

Fichiers séquentiels indexés et B-arbres Question posée à l'examen du 15 octobre 1996 a) Quelle est la taille de l'espace disque nécessaire pour être sûr de pouvoir créer un fichier séquentiel indexé qui doit contenir 1'000'000 éléments, sachant qu'un élément nécessite une place de 76 octets, dont une clé de 8 octets, que les blocs de données ont une taille de 1536 octets et les blocs d'index 1024 octets et que les pages de données sont initialement remplies à 80%? On supposera que les références, dans un bloc d'index, à un autre bloc d'index ou à un bloc de donnée, tiennent sur 4 octets. Justifiez votre réponse et donnez le détail des calculs. En plus de la taille de l'espace disque, vous indiquerez, entre autres, le nombre de blocs de données, la profondeur de l'arborescence des blocs d'index et le nombre de blocs d'index à chaque niveau. b) Pour les mêmes données (même nombre et même taille d'élément), quelle sera la taille de l'espace disque nécessaire et le nombre de niveaux si l'on utilise une structure de B-arbre avec des pages de 1024 octets (donnez les valeurs minimales et maximales possibles, dans l'hypothèse de pages à moitié pleines ou entièrement pleines)? Là aussi, justifiez votre réponse et donnez le détail des calculs: ordre du B-arbre, nombre de pages minimum et maximum, ... N.B. Comme pour le séquentiel indexé, les références à une page occupent 4 octets. Solution Exercice suivant

http://cuisung.unige.ch/std/ex/14/2a.html [23-09-2001 16:03:28]

Structuration des Données Informatiques - 7.2, exercice 1

Chaînes mono-directionnelles Question posée à l'examen écrit du 9 juillet 1996 Soit une d`une chaîne monodirectionnelle avec des éléments entiers. Ecrivez une procédure Pascal qui supprime à la fois le premier et le dernier élément de la chaîne, et ceci de manière répétitive, jusqu`a ce qu'il ne reste qu'un seul élément, ou jusqu'a ce que la chaîne soit vide. La procédure donnera comme résultat soit le dernier élément restant, soit le pointeur "nil". Exemples: 1.

Dans ce cas, on supprime les éléments contenant les valeurs entièlres 2 et -1, et le résultat de la procédure sera alors 3. 2.

Dans ce cas, on supprimera d'abord 2 et 5, ensuite 3 et -1, et le résultat sera alors "nil". Solution

http://cuisung.unige.ch/std/ex/7/2a.html [23-09-2001 16:03:36]

Structuration des Données Informatiques - 11.3, exercice 2

Exercice suivant

Réseau autoroutier Soit un réseau autoroutier tel que celui-ci:

1. Quelle structure(s) de donnée(s) utiliseriez-vous pour le représenter; dessinez-la. 2. Donnez le détail des déclarations que vous feriez, en Pascal. 3. Ecrivez une fonction qui déterminera la distance minimale à parcourir entre deux villes données en paramètre. Solution Exercice suivant

http://cuisung.unige.ch/std/ex/11/3b.html [23-09-2001 16:04:08]

Structuration des Données Informatiques - 7.4, exercice 1

Exercice suivant

Anneaux bidirectionnels Question posée au conctrôle continu du 17 juin 1996 On vous fournit un entier ainsi qu'un anneau bidirectionnel ayant comme éléments des entiers, pouvant être négatifs. On vous demande de vous déplacer dans l'anneau à la position absolue donnée par l'entier qui vous est donné. Là, vous prenez l'entier qui se trouve dans l'élément courant, vous supprimez l'élément courant, et vous vous déplacez dans l'anneau, cette fois-ci de façon relative à la position courante en fonction du nombre qui s'y trouvait. Vous devez répéter ces pas (prendre l'entier, supprimer l'élément, se déplacer) jusqu'à ce que il n'y ait plus d'élément dans l'anneau, jusqu'à ce que vous sortiez de l'anneau, ou bien jusqu'à ce que vous rencontriez la valeur 0 (zéro) dans l'anneau. (Attention, si vous arrivez à la fin de l'anneau, il ne faut pas repartir depuis le début; de même, si on arrive au début, il ne faut pas continuer à la fin). On vous demande de fournir, dans un paramètre de sortie, le type d'arrêt et d'imprimer, dans la procédure, les valeurs se trouvant dans les éléments visités. Utilisez les déclarations suivantes: type TypeArret = (SortieAnneau, ElementNul, AnneauVide); Anneau = ^Element; Element = record Entier : Integer; Predecesseur, Succeseur : Anneau; end; { Element } procedure DeplacerDansAnneau(var UnAnneau : Anneau; Deplacement: integer; var Arret : TypeArret); Exemple:

Dans le cas ci-dessus, si l'entier donné initialement est 1, on va à la première position, on prend 2, on l'imprime et on supprime la première position de l'anneau. On se déplace en avant de 2 positions (correspondant à la position 3 dans l'anneau initial), on prend -2, on l'imprime et on supprime l'é lément. Ensuite il faut signaler la fin du programme, parce qu'avant l'élément que l'on vient de suprimer il n'y a qu'un seul élément (contenant 4) et l'on ne peut donc pas se déplacer de 2 éléments en arrière. Solution Exercice suivant

http://cuisung.unige.ch/std/ex/7/4a.html [23-09-2001 16:04:14]

Structuration des Données Informatiques - 8.1, exercice 1

Exercice suivant

Arbre de tri Question posée au conctrôle continu du 17 juin 1996 a) Etant donné l'arbre de tri suivant, donnez une séquence possible des données fournies en entrée qui aurait permis d'aboutir à l'arbre de tri en question:

b) idem pour l'arbre suivant:

Solution Exercice suivant

http://cuisung.unige.ch/std/ex/8/1a.html [23-09-2001 16:04:24]

Structuration des Données Informatiques - 11.5, exercice 1

Exercice suivant

Tri topologique inverse Question posée au conctrôle continu du 17 juin 1996 En s'inspirant de la description de graphes non-orientés en termes de type abstrait vue au cours, nous allons supposer que les types "Graphe" et "SerieDeSommets" ont été définis, sans que vous ne connaissiez les détails de ces structures. Nous allons aussi supposer que les primitives suivantes sont à votre disposition: function Index(NomSommet: string; LeGraphe: Graphe): integer; { retourne un numero compris entre 1 et MaxNbSommets } function NomSommet(IndexSommet: integer; LeGraphe: Graphe) :string; { retourne le nom du sommet dont l'index est fourni } function NombreDeSommets(LeGraphe: Graphe): integer; {retourne le nombre de sommets effectifs composant le graphe} function SommetsVoisins(IndexSommet: integer; LeGraphe: Graphe): SerieDeSommets; { retourne une structure permettant de retrouver l'index des voisins immédiats } function PremierSommet(var UneSerie: SerieDeSommets): integer; { extrait le premier des sommets de la série et retourne son index } function SommetSuivant(var UneSerie: SerieDeSommets): integer; { extrait le prochain sommet de la serie & retourne son index} function FinDeSerie(UneSerie: SerieDeSommets): boolean; { vrai s'il n'y a plus de sommet suivant dans la serie } En utilisant ces primitives, tout en ignorant de quelle façon la structure de graphe est implantée, écrivez une procédure "TriTopologiqueInverse(LeGraphe: Graphe)" qui imprime les sommets du graphe dans l'ordre topologique inverse. Solution Exercice suivant

http://cuisung.unige.ch/std/ex/11/5a.html [23-09-2001 16:04:26]

Structuration des Données Informatiques - 14.3, exercice 1

Exercice suivant

B-arbre Question posée au contrôle continu du 17 juin 1996 Dessinez le B-arbre résultant de la suppression de la valeur g dans le B-arbre d'ordre 1 suivant:

Solution Exercice suivant

http://cuisung.unige.ch/std/ex/14/3a.html [23-09-2001 16:04:59]

Structuration des Données Informatiques - 7.4, exercice 2

Exercice suivant

Chaînes bidirectionnelles Question posée au conctrôle continu du 20 juin 1995 On dispose d'une chaîne bidirectionnelle avec des éléments contenant un nombre entier (pouvant être négatif). Ecrire une procédure qui reçoive en paramètre la chaîne et un entier, puis se déplace à la position dans la chaîne indiquée par cet entier et utilise le contenu de cette position (nombre entier pouvant être négatif) pour se déplacer à nouveau, mais cette fois de manière relative à la position courante. La procédure réitère ces déplacement relatifs en fonction de la nouvelle position courante jusqu'à ce qu'un déplacement la fasse sortir de la chaîne ou que l'on revienne sur un élément déjà visité. La procédure retournera alors le type d'arrêt et la position du dernier élément examiné. Exemple:

Si l'on donne à la procédure le nombre 1, elle ira examiner le 1er élément de la chaîne, qui contient la valeur 2. Elle ira ensuite examiner la position 3 (position courante=1, déplacement relatif=2), puis la position 2 (position courante=3, déplacement relatif=-1) et s'arrêtera là car la prochaine position serait 6 et que la chaîne est de longueur 4. N.B.: En plus de la procédure, donner les déclarations de type nécessaires pour la structure de chaîne. Solution Exercice suivant

http://cuisung.unige.ch/std/ex/7/4b.html [23-09-2001 16:05:04]

Structuration des Données Informatiques - 8.2, exercice 1

exercice suivant

Arbre lexicographique Question posée au contrôle continu du 20 juin 1995 On veut construire un arbre multiple d'ordre 26 permettant de stocker des mots d'un dictionnaire de sorte que les chemins partant de la racine représentent des mots du dictionnaire, de la façon suivante

Les arcs sont étiquettés avec les lettres de l'alphabet (on suppose ici que l'on ne tient pas compte des accents sur les lettres) et les noeuds contiennent un booléen indiquant si le chemin de la racine à ce noeud représente un mot complet ou pas (sur le dessin - = faux et * = vrai). En utilisant la possibilité que donne le langage Pascal d'indexer un tableau de pointeurs à l'aide d'un intervalle de caractères afin de représenter les étiquettes des arcs, donner: a) les déclarations de types et de variables nécessaires à la construction d'un tel dictionnaire, b) une fonction booléenne ayant pour paramètre le dictionnaire et un string et indiquant si le mot contenu dans le string se trouve dans le dictionnaire, c) une procédure imprimant touts les mots du dictionnaire dans l'ordre alphabétique. Solution exercice suivant

http://cuisung.unige.ch/std/ex/8/2a.html [23-09-2001 16:05:07]

Structuration des Données Informatiques - 11.3, exercice 1

Exercice suivant

Plus courts chemins dans un graphe Question posée au conctrôle continu du 20 juin 1995 En s'inspirant de la méthode de Warshall (page 157 du livre) pour déterminer la fermeture transitive d'un graphe représenté par une matrice de connectivité, dériver un algorithme construisant une matrice de valeurs numériques indiquant la longueur du plus court chemin entre tous les divers noeuds d'un graphe. Une approche simple consiste à d'abord construire la matrice résultat à partir de la matrice de connectivité, en mettant la valeur 1 là où il y a des arcs dans la matrice de connectivité. Puis, selon la méthode de Warshall, examiner toutes les combinaisons X->Y->Z telles qu'il existe un chemin de X vers Y et de Y vers Z et comparer la longueur de X->Y + Y->Z avec le contenu de la matrice résultat pour la case (X,Z). Si la somme est plus petite, elle remplacera l'ancienne valeur de la case (X,Z). (Faites bien attention à l'initialisation de la matrice résultat!) Solution Exercice suivant

http://cuisung.unige.ch/std/ex/11/3a.html [23-09-2001 16:05:09]

http://cuisung.unige.ch/std/ex/7/2a.txt

type versElement = ^Element; Element = record info : integer; suivant : versElement; end; { Debut est le pointeur de debut de chaine, Resultat contiendra le resultat - nil ou un pointeur vers un element de la chaine } procedure Suppression(var Debut, Resultat : versElement); var courant : versElement; fin : boolean; begin fin := false; while not fin do begin if Debut = nil then begin {chaine vide} fin := true; Resultat := nil; end else if Debut^.suivant = nil then begin {un seul element} Resultat := Debut; fin := true; end else begin {on efface le premier element} courant := Debut; Debut:= Debut^.suivant; dispose(courant); if Debut^.suivant = nil then begin {il y avait 2 el} dispose(Debut); Resultat := nil; fin := true; end else begin {plus de 2 elements} courant := Debut; { on est sur qu'il n'est pas nil} while courant^.suivant^.suivant nil do courant := courant^.suivant; dispose(courant^.suivant); courant^.suivant:=nil; {c'est bien necessaire afin d'indiquer la fin de la chaine} end; {else/begin} end; {else/begin} end; {while} end; {Suppression}

http://cuisung.unige.ch/std/ex/7/2a.txt [23-09-2001 16:06:38]

http://cuisung.unige.ch/std/ex/8/2e.txt

{ version recursive } function Trouve(Mot: string; Dico: VersNoeud): boolean; begin { Trouve } if Dico=nil then Trouve := false else if Mot = '' then Trouve := Dico^.Complet else Trouve := Trouve(Dico^.Desc[Mot[1]], copy(Mot,2,length(Mot)-1)); end; { Trouve } { version non-recursive } function Trouve(Mot: string; Dico: VersNoeud) : boolean; var i: integer; Courant: VersNoeud; begin { Trouve } i:=1; Courant := Dico; while (i P^.nombre then Ok := false else LastVal := P^.nombre Parcours(P^.droite); end; (* Parcours *) begin Ok:= true; LastVal:= -MaxInt; Parcours(Racine); return Ok; end; (* verifieArbre *)

http://cuisung.unige.ch/std/ex/8/1eSol.html (2 of 2) [23-09-2001 16:15:13]

http://cui.unige.ch/eao/www/std/ex/7/4j.txt

procedure Tri(var Anneau: VersAnneau); var P1, P2, Dernier, Pred, Suiv, NextInnerStep, NextOuterStep: VersAnneau; begin (* Tri *) if Anneau nil then if Anneau Anneau^.Suivant then begin (* anneau a au moins 2 elem. *) Dernier := Anneau^.Precedent; if Dernier = Anneau^.Suivant then begin (* que 2 elem. au total *) if P1^.Info > P2^.Info then Anneau := Dernier; end else begin (* l'anneau a au moins 3 elem. *) P1 := Anneau; while P1 Dernier do begin NextOuterStep := P1^.Suivant; P2 := NextOuterStep; while P2 Anneau do begin NextInnerStep := P2^.Suivant; if P1^.Info > P2^.Info then begin if P1^.Suivant = P2 then (* permute deux elem. adjascents *) with P1^ do begin Pred := Precedent; Suiv := P2^.Suivant; Precedent := P2; Suivant := Suiv; Pred^.Suivant := P2; P2^.Precedent := Pred; P2^.Suivant := P1; Suiv^.Precedent := P1; end (* with *) else if P1^.Precedent = P2 then (* perm. premier et dernier *) with P1^ do begin Pred := P2^.Precedent; Suiv := P1^.Suivant; Precedent := Pred; Suivant := P2; Suiv^.Precedent := P2; Pred^.Suivant := P1; P2^.Precedent := P1; P2^.Suivant := Suiv; end (* with *) else with P1^ do begin (* perm. 2 el. separes par au moins 1 el *) Pred := Precedent; Suiv := Suivant; Precedent := P2^.Precedent; Suivant := P2^.Suivant; Pred^.Suivant := P2; Suiv^.Precedent := P2; P2^.Precedent := Pred; P2^.Suivant := Suiv; Pred := Precedent; Suiv := Suivant; Pred^.Suivant := P1; Suiv^.Precedent := P1; end; (* with *) if Anneau = P1 then Anneau := P2; P2 := NextInnerStep; end; (* while P2 *) P1 := NextOuterStep; end; (* while P1 *) end; (* if *) end; (* if *) end; (* Tri *)

http://cui.unige.ch/eao/www/std/ex/7/4j.txt [23-09-2001 16:16:25]

solution, 8.3 exercice 2

1.

2.

http://cui.unige.ch/eao/www/std/ex/8/3b.sol.html [23-09-2001 16:16:54]

http://cuisung.unige.ch/std/ex/7/4i.txt

procedure InsereFin(var Anneau: PtrNoeud; LaDonnee: integer); var Nouveau: PtrNoeud; begin if Anneau = nil then begin new(Anneau); with Anneau^ do begin Preced:= Anneau; Suivant:= Anneau; Donnee:= LaDonnee; end; (* with *) end (* then *) else begin new(Nouveau); with Nouveau^ do begin Donnee:= LaDonnee; Suivant:= Anneau; Preced:= Anneau^.Preced; Anneau^.Preced^.Suivant := Nouveau; Anneau^.Preced := Nouveau; end; (* with *) end; (* if *) end; (* InsereFin *) function NbElem(Anneau: PtrNoeud): integer; var Courant: PtrNoeud; Nb: integer; begin if Anneau = nil then NbElem := 0 else begin Courant := Anneau^.Suivant; Nb := 1; while Courant Anneau do begin Courant := Courant^.Suivant; Nb := succ(Nb); end; (* while *) NbElem := Nb; end; (* if *) end; (* NbElem *) procedure Split(Ring: PtrNoeud; Data: integer; var LowerRing, HigherRing: PtrNoeud); var Courant: PtrNoeud; begin LowerRing := nil; HigherRing := nil; if Ring nil then begin Courant := Ring; repeat if Courant^.Donnee < Data then InsereFin(LowerRing, Courant^.Donnee) else InsereFin(HigherRing, Courant^.Donnee); Courant := Courant^.Suivant; until Courant=Ring; end; (* if *) end; (* Split *)

http://cuisung.unige.ch/std/ex/7/4i.txt [23-09-2001 16:17:45]

http://cuisung.unige.ch/std/ex/8/1d.txt

1) Arbre('-', Arbre('*', Feuille('5'), Arbre('-', Feuille('4'), Arbre('+', Feuille('3'), Arbre('-', nil, Arbre('-', nil, Feuille('2') ) ) ) ) ), Arbre('/', Arbre('-', Feuille('1'), Feuille('9') ), Arbre('+', nil, Arbre('*', Feuille('8'), Feuille('7') ) ) ) ) 2) function Feuille(Contenu: integer): integer; begin Feuille := Contenu; end; (* Feuille *) function Arbre(ContenuRacine: char; Gauche, Droit: integer): integer; (* Dans ce cas, il faut remplacer dans l'expression 1) les "nil" par des "0" *) begin case ContenuRacine of '+': Arbre := Gauche + Droit; '-': Arbre := Gauche - Droit; '*': Arbre := Gauche * Droit; '/': Arbre := Gauche div Droit; end; (* case *) end; (* arbre *)

http://cuisung.unige.ch/std/ex/8/1d.txt [23-09-2001 16:18:07]

http://cuisung.unige.ch/std/ex/7/4h.txt

function Inverse(Ring: VersAnneau): VersAnneau; var Fin, { sert a memoriser la fin de l'anneau resultant } Courant, { sert a parcourir l'anneau d'entree } Invers: VersAnneau; { pointeur debut de l'anneau resultant } begin if Ring=nil then Inverse:=nil { si l'anneau est vide, le resultat est vide } else begin new(Fin); { cree l'element qui sera a la fin de l'anneau resultant } Fin^.Info := Ring^.Info; { y copie l'info du ler elt. de l'anneau d'entree } Invers := Fin; { le pointeur debut pointe sur l'elt que l'on vient de creer} Courant := Ring^.Suivant; { on va parcourir le reste de l'anneau d'entree } while CourantRing do begin {boucle tant qu'on n'est pas revenu au 1er elt} new(Tmp); { cree un nouvel element } with Tmp^ do begin Info := Courant^.Info; { y copie l'info de l'element courant } Suivant := Invers; { fait une insertion debut dans l'anneau } Suivant^.Precedent := Tmp; { resultant sans se preoccuper de fermer } end; { with } { l'anneau a chaque fois } Invers := Tmp; Courant := Courant^.Suivant; end; { while } Fin^.Suivant := Invers; { reste a ferme l'anneau en reliant le premier } Invers^.Precedent := Fin;{ element au dernier, dans les deux sens } Inverse:= Invers; end; { if } end; { Inverse } function estInverse(Ring1, Ring2: VersAnneau): boolean; var Different: boolean; Cur1, Cur2: VersAnneau; begin if Ring1=nil then estInverse := Ring2=nil else if Ring2=nil then estInverse := false else begin Cur1 := Ring1; Cur2 := Ring2^.Precedent; repeat Different := Cur1^.InfoCur2^.Info; Cur1 := Cur1^.Suivant; Cur2 := Cur2^.Precedent; until Different or (Cur1=Ring1) or (Cur2=Ring2); estInverse := not Different and (Cur1=Ring1) and (Cur2=Ring2); end; { if } end; { estInverse }

http://cuisung.unige.ch/std/ex/7/4h.txt [23-09-2001 16:19:11]

Le chemin le plus court/Examen 30.6.1999

Le chemin le plus court Solution pour la question posée à l'examen écrit le 30.6.1999 contenu du FIFO étape

L1 en notation Scheme

1 2 3 4 5 3

() ((1)) () () ((2 1) (4 1)) ((4 1))

non défini non défini (1) (1) (1) (2 1)

4 5 3 4 5 3 4 5 3 4 5 3 4 (TROUVE)

((4 1)) ((4 1) (5 2 1)) ((5 2 1)) ((5 2 1)) ((5 2 1) (7 4 1)) ((7 4 1)) ((7 4 1)) ((7 4 1) (6 5 2 1)) ((6 5 2 1)) ((6 5 2 1)) ((6 5 2 1)) () ()

(2 1) (2 1) (4 1) (4 1) (4 1) (5 2 1) (5 2 1) (5 2 1) (7 4 1) (7 4 1) (5 2 1) (6 5 2 1) (6 5 2 1)

Le chemin le plus court est: 1 2 5 6 Wolfgang Müller Last modified: Thu Aug 19 00:11:24 MEST 1999

http://cuisung.unige.ch/std/ex/11/a_solution.html [23-09-2001 16:19:43]

13.4 exercice 3, solution

. Les parties importantes du code à réaliser sont: 1. Initialisation des coefficients (1 pt) 2. Parcours de l'espace des solutions (6 pts) 3. Fonction vérifiant si les coefficients trouvés produisent un H-code parfait (3 pts) 4. Boucle principale, testant toutes les solutions, minimisant la taille (2 pts) 1) procedure initialiseCoefficients; var i : integer; begin for i = 1 to LongueurMax do Coeff[i] := 0; end;

2) function incrementeCoefficients : boolean; begin while ( index < LongueurMax AND Coeff[index] = MaxCoeff ) do begin Coeff[index] := 0; index := index + 1; end; {while} if ( index > LongueurMax ) then begin incrementeCoefficients := false; else begin Coeff[index] := Coeff[index] + 1; index := 0; end; {if} end; {function}

3) function estParfaite : boolean; var i : integer, code : integer; begin for i = 1 to MaxIndice do tab[i] := false; for i = 1 to NbMots do begin code := H(Vocabulaire[i]); if ( tab[code] = true ) then begin estParfaite := false; exit function; end tab[code] := true; end; {for} end; {function}

4) begin for Taille = NbMots to TailleMax do begin initialiseCoefficients; while incCoeffs do if estParfaite then exit procedure; end; {while}

http://cuisung.unige.ch/std/ex/13/4c.sol.html (1 of 2) [23-09-2001 16:20:13]

13.4 exercice 3, solution

end; {for} { si on arrive la, aucune fonction parfaite n'a été trouvée. } end. {procedure chercheCoefficients} b. Les parties importantes du code a réaliser sont: 1. Comparaison des probabilités du mot à insérer et du mot se trouvant déjà dans la table (1 pt) 2. Remplacement du mot dans la table par le nouveau mot (si sa prob est supérieure) (1 pt) 3. Insertion du mot qui vient d'être remplacé (1 pt) function Insert( X : string ) : integer; var H0, hi : integer; temp : string; begin H0 := H(X); hi := H0; while ( T[hi] '' ) and ( T[hi] X ) do begin -----------------------------------------------------1) if ( P(X) > P(T[hi]) ) then begin 2)

temp := T[hi]; T[hi] := X; { solution 1 : simplement rappeler la fonction insert ... }

3a)

Insert( temp );

3b)

{ solution 2 : trouver la nouvelle valeur de hi et continuer... mais comme les collisions sont traitées de façon linéaire, cette partie est inutile dans ce cas. } X = temp;

else begin --------------------------------------------------------------------hi := (hi+1) mod MaxElements; if hi = H0 then begin writeln('tableau plein'); exit(program); end; end; end; if T[Hi] = '' then T[Hi] := X; Insert := hi; end;

http://cuisung.unige.ch/std/ex/13/4c.sol.html (2 of 2) [23-09-2001 16:20:13]

Structuration des Donn es Informatiques - 11.3, solution ex. 3

(question) . Si l'on adopte la convention que x->y signifie "x est plus jeune que y", on obtient le graphe suivant:

Si l'on adopte la convention que x->y signifie "x est plus vieux/vieille que y", on obtient le graphe suivant:

b. C Arc: A A l ligne vers colonne l n a = i d u est plus jeune que c r d e é e

J e a n

J e a n n e

J a c q u e s

M a r i e

P a u l

P i e r r e

Y v e s

Alice

F F F F F F F F V V

André

F F V F F F F F V F

Claude

F F F F F F F F V V

Jean

F F F F F F F V V F

Jeanne

F F F V F F F F F F

Jacques

F F F F V F F F V F

Marie

F F F F F V F F F F

http://cuisung.unige.ch/std/ex/11/3c.sol.html (1 of 2) [23-09-2001 16:20:56]

Structuration des Donn es Informatiques - 11.3, solution ex. 3

Paul

F F F F F F F F F F

Pierre

F F F F F F F V F F

Yves

F F F F F F F V F F

avec cette même matrice, on pourrait considérer que les arcs vont de la colonne vers la ligne et signifient "est plus vieux que" c. C Arc: A A l ligne vers colonne l n a = i d u est plus jeune que c r d e é e

J e a n

J e a n n e

J a c q u e s

M a r i e

P a u l

P i e r r e

Y v e s

Alice

F F F F F F F V V V

André

F F V F F F F V V V

Claude

F F F F F F F V V V

Jean

F F F F F F F V V F

Jeanne

F F F V F F F V V F

Jacques

F F F V V F F V V F

Marie

F F F V V V F V V F

Paul

F F F F F F F F F F

Pierre

F F F F F F F V F F

Yves

F F F F F F F V F F

Cette fermeture transitive permet de facilement trouver qui est certainement plus jeune ou plus vieux qu'une personne donnée. Pour trouver qui est certainement plus vieux que X, il suffit de regarder la ligne contenant X et chercher les colonnes où il y a un "V". Pour trouver qui est certainement plus jeune que X, il suffit de regarder la colonne contenant X et chercher les lignes contenant un "V" On ne peut par contre pas dire qui est lel plus vieux ou le plus jeune, car nous ne sommes pas en présence d'une relation d'ordre totale et il n'y a peut-être aucun moyen de dire qui est le plus vieux (la plus vielle) ou le (la) plus jeune. En l'occurrence, Alice, André et Marie sont les trois plus jeunes, mais on ne peut rien dire sur leurs ages respectifs. d. Marie, Alice, André, Jacques, Claude, Yves, Jeanne, Jean, Pierre, Paul. D'autres possibilités consisteraient à permuter Alice, Marie et André (toutes les permutations sont possibles puisqu'il n'y a aucune relation directe entre eux).

http://cuisung.unige.ch/std/ex/11/3c.sol.html (2 of 2) [23-09-2001 16:20:56]

Structuration des Donn es Informatiques - 14.3, solution ex. 4

(question) . Insertion de 1, puis de 2: 1

- 1 2

Insertion de 3, puis de 6, puis de 7: 2

2

3

1

-

3

1

3 6

1 2

6 7

Insertion de 4, puis de 5: 3

6

3

6

1 2

4

7

1 2

4 5

7

Insertion de 8: 3 1 2

6 4 5

7 8

Insertion de 9: 6 3 1 2

8 4 5

7

9

b. Si chaque page occupe 512 octets et qu'une page contient au minimum 1 donnée et au maximum 2 données (b-arbre d'ordre 1), le cas le plus défavorable est quand toutes les pages ne contiennent qu'une donnée chacune et le cas le plus favorable est lorsque toutes les pages contiennent deux données chacune. L'espace utilisé est respectivement: ❍ 10'000 données et 1 donnée/page => 10'000 pages = 10'000*512 octets ❍ 10'000 données et 2 données/page => 5'000 pages = 5'000*512 octets c. Quand les pages sont pleines, les différents niveaux contiennent: niveau nb. pages du niveau nb. pages cumulés 1

1

1

2

3

4

3

9

13

4

27

40

http://cuisung.unige.ch/std/ex/14/3d.sol.html (1 of 2) [23-09-2001 16:21:50]

Structuration des Donn es Informatiques - 14.3, solution ex. 4

5

81

121

6

243

364

7

729

1093

8

2187

3280

9

6561

9841

Quand les pages ne sont qu'à moitié pleines, les différents niveaux contiennent: niveau nb. pages du niveau nb. pages cumulés 1

1

1

2

2

3

3

4

7

4

8

15

5

16

31

6

32

63

7

64

127

8

128

255

9

256

511

10

512

1'023

11

1024

2'047

12

2048

4'095

13

4096

8'191

14

8192

16'383

On voit donc qu'il faut au minimum 9 niveaux pour avoir 5'000 pages pleines et au plus 14 niveaux pour avoir 10'000 pages à moitié pleines

http://cuisung.unige.ch/std/ex/14/3d.sol.html (2 of 2) [23-09-2001 16:21:50]

Structuration des Donn es Informatiques - 13.4, solution exercice 2

(question) Pour le tableau ci-dessous, on a supposé que la position initiale d'un mot est calculée comme étant H0(K)=(H(K) mod 15)+1 indice

contenu

Nb.collisions positions examinées

1

lumiere

0

1

2

soudaine

1

9, 2

3

une

0

3

4

etait

0

4

5

traversa

3

11, 4, 12, 5

6

qu

0

6

7

du

0

7

8

la

0

8

9

si

1

7, 9

10

illumination 0

10

11

jour

0

11

12

son

2

6, 9, 12

13

forte

0

13

14

esprit

0

14

15

http://cuisung.unige.ch/std/ex/13/4b.sol.html [23-09-2001 16:22:27]

http://cuisung.unige.ch/std/ex/8/2c.txt

program Lexico; type VersNoeud= ^Noeud; Noeud= record Desc: array['a'..'z'] of VersNoeud; Complet: boolean; end; { Noeud } var Dico: VersNoeud; Longueur: integer; function Lecture(NomFichier: string): VersNoeud; var F: text; Status: integer32; i: integer; l: char; Mot: string; Rac, P: VersNoeud; begin (* Lecture *) new(Rac); open(F, NomFichier,'old', Status); if Status 0 then begin writeln('probleme pour ouvrir le fichier'); halt; end; reset(F); while not eof(F) do begin Read(F,Mot); P:= Rac; (* for i := 1 to length(Mot) do begin *) i := 1; while Mot[i] ' ' do begin if P^.Desc[Mot[i]] = nil then begin new(P^.Desc[Mot[i]]); with P^.Desc[Mot[i]]^ do begin Complet := false; for l:='a' to 'z' do Desc[l] := nil; end; (* with *) end; (* if *) P:= P^.Desc[Mot[i]]; i:= i+1; end; (* while *) P^.Complet := true; readln(F); end; (* while not eof *) Lecture := Rac; end; (* Lecture *) function NbMots(Longueur: integer; Dico: VersNoeud):integer; var Nb: integer; procedure Parcours1Niveau(Rac: VersNoeud; NiveauxRestants: integer); var Reste: integer; l: char; begin (* Parcours1Niveau *) if Rac nil then if NiveauxRestants = 0 then begin if Rac^.Complet then Nb := succ(Nb) end else begin if NiveauxRestants = -1 then begin Reste := NiveauxRestants;

http://cuisung.unige.ch/std/ex/8/2c.txt (1 of 2) [23-09-2001 16:23:02]

http://cuisung.unige.ch/std/ex/8/2c.txt

if Rac^.Complet then Nb := succ(Nb) end else Reste := pred(NiveauxRestants); for l := 'a' to 'z' do if Rac^.Desc[l] nil then Parcours1Niveau(Rac^.Desc[l], Reste); end; (* else *) end; (* Parcours1Niveau *) begin (* NbMots *) Nb := 0; if Longueur = 0 then Parcours1Niveau(Dico, -1) else Parcours1Niveau(Dico, Longueur); NbMots := Nb; end; (* NbMots *) begin (* Dico := PseudoLecture; *) readln(Longueur); Dico := Lecture('990229.dat'); writeln('Nb. mots de longueur', Longueur, '=', NbMots(Longueur,Dico)); end.

http://cuisung.unige.ch/std/ex/8/2c.txt (2 of 2) [23-09-2001 16:23:02]

http://cuisung.unige.ch/std/ex/11/5b.txt

procedure TriTopoInverse(LeGraphe: Graphe); const MaxNbSommets=20; var i, CmptrVisite, IndexSommet : 0..MaxNbSommets; NumDOrdre : array[1..MaxNbSommets] of integer; Parcouru:array[1..MaxNbSommets] of boolean; NbSommets: integer; procedure Visite (IndexSommet : integer); var AutreSommet : integer; Voisins: SerieDeSommets; begin CmptrVisite := CmptrVisite + 1; NumDOrdre[IndexSommet] := CmptrVisite; Parcouru[IndexSommet] := true; Voisins := SommetsVoisins(IndexSommet, LeGraphe); while not FinDeSerie(Voisins) do begin AutreSommet := ExtraitSommet(Voisins); if Parcouru[AutreSommet] then writeln(NomSommet(AutreSommet,LeGraphe), ' fait partie d''un cycle') else if NumDOrdre[AutreSommet] = 0 then Visite (AutreSommet); end; { while } Parcouru[IndexSommet] := false; write(NomSommet(IndexSommet,LeGraphe)); end; { Visite } begin { TriTopoInverse } NbSommets := NombreDeSommets(LeGraphe); CmptrVisite := 0; for IndexSommet := 1 to NbSommets do NumDOrdre[IndexSommet]:=0; for IndexSommet := 1 to NbSommets do if NumDOrdre[IndexSommet]=0 then begin for i := 1 to NbSommets do Parcouru[i] := false; Visite (IndexSommet); end; { if } end; { TriTopoInverse }

http://cuisung.unige.ch/std/ex/11/5b.txt [23-09-2001 16:23:32]

Structuration des Données Informatiques - 14.3, solution 3

Nous allons considérer deux cas, suivant que l'on considère qu'une page ne contient que les données et les pointeurs vers les pages descendantes ou que l'on compte, en plus, un compteur indiquant le nombre effectif de données dans la page

Cas où une page ne contient pas de compteur . Puisqu'il y a un pointeur de plus que de données, le nombre de données par page est: (1024-4) div (47+4) = 20 l'ordre du B-arbre est donc de 10 et nous arondissons celui du B*-arbre à 14. b. Pour le B-arbre: ❍ La page racine peut contenir au minimum 1 donnée, reste 999'999 données à répartir au minimum 10 par page. Le nombre total de pages, quand celles-ci sont remplies au minimum est: 1+(999'999 div 10) = 100'000 pages (soit 100'000 KiloOctets) ❍ Si toutes les pages sont entièrement remplies, le nombre total de pages est: 1'000'000 div 20 = 50'000 pages (soit 50'000 KiloOctets) Pour le B*-arbre: ❍ La page racine peut contenir au minimum 1 donnée, reste 999'999 données à répartir au minimum 14 par page. Le nombre total de pages, quand celles-ci sont remplies au minimum est: 1+(999'999 div 14) = 71'429 pages (soit 71'429 KiloOctets) ❍ Si toutes les pages sont entièrement remplies, le nombre total de pages est le même que pour le B-arbre, soit 50'000 pages. c. Pour le B-arbre: ❍ Quand les pages sont remplies au minimum, les niveaux successifs contiennent le nombre de pages suivant: 1, 2, 22, 242, 2662, 29'282, 322'102



Il faut donc au moins 7 niveaux pour arriver à un total de 100'000 pages Quand les pages sont remplies au maximum, les niveaux successifs contiennent le nombre de pages suivant: 1, 21, 441, 9'261, 194'481 Il faut donc au moins 5 niveaux pour arriver à un total de 50'000 pages

Pour le B*-arbre: ❍ Quand les pages sont remplies au minimum, les niveaux successifs contiennent le nombre de pages suivant: 1, 2, 30, 450, 6'750, 101'250 Il faut donc au moins 6 niveaux pour arriver à un total de 71'429 pages

http://cuisung.unige.ch/std/ex/14/3c.sol.html (1 of 2) [23-09-2001 16:24:06]

Structuration des Données Informatiques - 14.3, solution 3



Quand les pages sont remplies au maximum, le nombre de niveaux est le même que pour le B-arbre, soit 5 niveaux.

Cas où une page contient un compteur .

http://cuisung.unige.ch/std/ex/14/3c.sol.html (2 of 2) [23-09-2001 16:24:06]

solution de l'exercice 1, section 8.3

. la constrution est très similaire à celle d'un arbre binaire de tri, si ce n'est qu'à chaque fois qu'un noeud n'a pas de descendant droit, son pointeur droit pointe vers l'ancêtre dont le contenu est immédiatement supérieur au contenu du noeud courant, selon l'ordre de tri:

b. la suppression se fait de manière similaire à un arbre de tri: si l'élément à détruire a deux descendants, on échange le contenu du noeud à détruire avec celui du noeud le plus à droite de son sous-arbre gauche (ou le plus à gauche de son sous-arbre droit), puis l'on détruit ce dernier:

http://cuisung.unige.ch/std/ex/8/3a.sol.html [23-09-2001 16:25:42]

http://cuisung.unige.ch/std/ex/15/1b.txt

procedure AjouteRegle(Table:TableDecision;R:integer;var NewTable:TableDecision); { AjouteRegle insere la regle R de la table "Table" dans la table "NewTable" en supprimant la premiere condition } var c: integer; begin {AjouteRegle} NewTable.NbRegles := succ(NewTable.NbRegles); for c:=2 to Table.NbConditions do NewTable.ValCond[NewTable.NbRegles,c-1] := Table[R,c]; end; {AjouteRegle} function ConstruitArbre(Table: TableDecision): PtrNoeud; var NewTable: TableDecision; P: PtrNoeud; begin { ConstruitArbre } { si la table n'a pas de conditions, l'arbre sera vide } if Table.NbConditions il faudra 26 données/bloc. 1.d) ❍



Avec 26 données/bloc, 100'000 données occuperont (100'000/26) =3'847 blocs de données une paire (clé+réf. à une page) occupe 12 octets => 1 bloc d'index de 2'560 octets peut contenir 2'560/12 =213 paires clé+réf.



la couche d'index la plus basse doit contenir 3'847/213 =19 blocs d'index



la couche immédiatement supérieure contiendra 18/213 =1 bloc d'index le nombre total de blocs = 3'847 + 19 + 1 = 3'867 blocs et comme chaque bloc occupe 2'560 octets => la place disque occupée = (3'867*2'560) octets = 9'899'520 octets.



1.e) l'arborescence d'index a 2 niveaux 1.f) niveau 1: 1 bloc niveau 2: 19 blocs 1.g) 3'847 blocs de données Si l'on prend l'hypothèse que les blocs de données contiennent chacun une référence à un bloc de débordement, il ne peut pas y avoir de solution à la question 1.a, c'est-à-dire qu'il n'y a pas de taille de bloc de données qui permette de ne pas avoir d'espace disque inutilisé. Par contre, avec 19 données et des blocs de 1'536 octets on aura le plus petit gaspillage possible (12 octets). Pour s'en convaincre, on peut démontrer qu'il suffit d'examiner les 32 premiers multiples de 80 et calculer le nombre de pages de 512 octets qui permette de les contenir. En effet, si (n*80) + 4 = m*512 + gaspillage alors ((n+32) *80) + 4 = ((m+5)*512) + gaspillage

http://cuisung.unige.ch/std/ex/14/2b.sol.html (1 of 2) [23-09-2001 16:28:47]

Structures de Données, 2ème contrôle continu 1998, solution à la question 1

En d'autres termes, pour n données/bloc et (n+32) données/bloc, on a le même gaspillage (en valeur absolue!). 1.a) avec des blocs de 1'536 octets, on n'a que 12 octets de gaspillage 1.b) on a 1536 octets/bloc et 80 octets/donnée => 1 bloc=(1'536-4) div 80=19 données/bloc 1.c) round(19*80/100)=round(15,2)=15 données/bloc 1.d) ❍

avec 15 données/bloc, 100'000 données occuperont (100'000/15) =6'667 blocs de données une paire (clé+réf. à une page) occupe 12 octets => 1 bloc d'index de 1'536 octets peut contenir 1'536/12 =128 paires clé+réf.



la couche d'index la plus basse doit contenir 6'667/128 =53 blocs d'index



la couche immédiatement supérieure contiendra 53/128 =1 bloc d'index le nombre total de blocs = 6'667 + 53 + 1 = 6'721 blocs et comme chaque bloc occupe 1'536 octets => la place disque occupée = (6'721*1'536) octets = 10'323'456 octets.





1.e) l'arborescence d'index a 2 niveaux 1.f) niveau 1: 1 bloc niveau 2: 53 blocs 1.g) 6'667 blocs de données

http://cuisung.unige.ch/std/ex/14/2b.sol.html (2 of 2) [23-09-2001 16:28:47]

Structures de données: 2ème contrôle continu 1998, solution à la question 2

. B-arbre résultant de l'insertion de la valeur L dans le B-arbre initial:

b. B-arbre résultant de la suppression de la valeur C dans le B-arbre initial:

c. B-arbre résultant de l'insertion de la valeur Z dans le B-arbre initial:

d. B-arbre résultant de la suppression de la valeur S dans le B-arbre initial:

http://cuisung.unige.ch/std/ex/14/3g.sol.html (1 of 3) [23-09-2001 16:29:58]

Structures de données: 2ème contrôle continu 1998, solution à la question 2

autre solution:

e. B-arbre résultant de la suppression de la valeur P dans le B-arbre initial:

autre solution:

http://cuisung.unige.ch/std/ex/14/3g.sol.html (2 of 3) [23-09-2001 16:29:58]

Structures de données: 2ème contrôle continu 1998, solution à la question 2

http://cuisung.unige.ch/std/ex/14/3g.sol.html (3 of 3) [23-09-2001 16:29:58]

Structuration des Données Informatiques - 10.3, solution 2

3.a) On peut imaginer deux genres de solution. Dans la première, on utilise un graphe dont les arcs ne sont ni orientés, ni pondérés. Chaque noeud du graphe représente une case de la carte, et le nombre correspondant à son type de terrain est stocké dans l'enregistrement du noeud. Il y a un arc de chaque noeud à chacun de ses voisins accessibles. Il n'est pas nécessaire de représenter les cases impraticables dans le graphe. La représentation de la case B9 et ses voisines serait

L'autre genre de solution utilise un graphe dont les arcs sont orientés et pondérés. Un arc représente le coût d'aller d'une case à une de ses voisines (c'est-à-dire le coût pour arriver à la case voisine). La partie du graphe autour de la case B9 serait

3.b) Une matrice de connectivité serait la façon la plus efficace pour stocker les arcs, parce que leur densité (NbSommets*~4/NbSommets^2 = ~0.04) dépasse 3%, en fait. Puisque le nombre de noeuds est constant, on peut utiliser un tableau pour les stocker. Pour la première structure proposée ci-dessus, on pourrait utiliser les structures suivantes: const MaxNoeuds = 100; {Pour la carte donnée} type NoeudIntervalle = 1..MaxNoeuds; var {Matrice de connectivité} Connexe: packed array[NoeudIntervalle, NoeudIntervalle] of boolean; {On ne stocke que le coût associé a chaque noeud} CoutDeNoeud: array[NoeudIntervalle] of integer; 3.c) Pour trouver le chemin le plus court, j'utiliserai la recherche en largeur, parce qu'elle évite de visiter les chemins plus longs que le chemin recherché. Mais ce problème est différent: on ne cherche pas le chemin le plus court, on cherche le chemin du moindre coût. On ne peut pas dire qu'on a trouvé le bon chemin dès qu'on arrive au point B - il est possible

http://cuisung.unige.ch/std/ex/10/3b.sol.html (1 of 3) [23-09-2001 16:31:35]

Structuration des Données Informatiques - 10.3, solution 2

qu'il y ait un autre chemin, peut-être plus long, mais moins coûteux. J'utiliserais donc la recherche en profondeur avec "back-tracking" ainsi que quelques petites modifications: à tout instant, je garde le chemin du moindre coût déjà trouvé (dans un tableau, p. ex.), ainsi que le coût lui-même. Si le coût du chemin qu'on est en train de parcourir dépasse le coût du meilleur chemin déjà trouvé jusqu'à ce noeud là, on peut arrêter de suivre ce chemin. Sinon, quand on arrive au noeud d'arrivée, si le coût du chemin suivi est inférieur à celui du meilleur chemin déjà trouvé, on les échange. On continue jusqu'à ce qu'on ait essayé (peut être incomplètement) tous les chemins possibles. 3.d) Le programme principal: Lire les données; Créer le matrice de connectivité; Obtenir les noeuds de départ et arrivée; Initialiser les variables: MeilleurCoût := MaxNoeuds*MaxNoeuds*MaxCoûtDeNoeud; CheminTrouvé := Faux; Mettre CoûtJusquIci[i] à zero pour tous les noeuds i; TrouverCheminDuMoindreCoût(0, 1, NoeudDeDepart, NoeudDArrivee); si CheminTrouvé alors Ecrire MeilleurChemin et son coût sinon Ecrire "Pas de chemin entre NoeudDeDepart et NoeudDArrivée!" La procédure TrouverCheminDuMoindreCoût, qui est récursive: procedure TrouverCheminDuMoindreCoût(Coût, NombreDEtapes, Noeud, NoeudDArrivee); begin {Ajoute le noeud actuel au chemin qu'on est en train d'explorer} CeChemin[NombreDEtapes] := Noeud; inc(NombreDEtapes); {Est-ce qu'on a trouvé le noeud d'arrivée?} si Noeud = NoeudDArrivée begin CheminTrouvé := Vrai; si Coût < MeilleurCoût {On a trouvé un meilleur chemin, donc on le stocke} begin MeilleurCout := Coût; LongueurDuChemin := NombreDEtapes - 1; Copier CeChemin dans MeilleurChemin; end; end; sinon {ce n'est pas le noeud d'arrivée} begin {Ajoute le coût du noeud actuel au coût du chemin qu'on explore, et le stocke pour le noeud actuel} Coût := Coût + CoûtDeNoeud[Noeud]; CoûtJusquIci[Noeud] := Coût; Pour tous les noeuds i faire si Connexe[Noeud, i] et ((CoûtJusquIci[i] = 0) ou {c'est-à-dire pas encore visité} (Coût + CoûtDeNoeud[i] < CoûtJusquIci[i])) {Si on a déjà trouvé ce noeud en passant par un chemin moins coûteux, on n'étend plus ce chemin. Cette astuce réduit beaucoup le coût de la recherche.}

http://cuisung.unige.ch/std/ex/10/3b.sol.html (2 of 3) [23-09-2001 16:31:35]

Structuration des Données Informatiques - 10.3, solution 2

TrouverCheminDuMoindreCoût(Coût, NombreDEtapes, i, NoeudDArrivée); {sinon la procédure retourne, et le "back-tracking" commence} end; end;

http://cuisung.unige.ch/std/ex/10/3b.sol.html (3 of 3) [23-09-2001 16:31:35]

http://cuisung.unige.ch/std/ex/7/4f.txt

procedure Paragraphes(UnTexte: VersLigne; var ChainePara: PtrPara); var P: VersLigne; Para: PtrPara; L: integer; NotDone: boolean; begin { Paragraphes } ChainePara := nil; P := UnTexte; L := 1; repeat { determine s'il y a lieu de sauter des lignes vides } if P=nil then NotDone := false else NotDone := P^.Texte=''; { tant que NotDone est vrai, on saute des lignes vides } while NotDone do begin P := P^.LigneSuivante; L := L+1; if P=nil then NotDone := false else NotDone := P^.Texte=''; end; { while } { on a fini de sauter des lignes vides, reste-t-il encore qq chose?} if Pnil then begin { on est sur le debut d'une serie de lignes non vides, il faut donc creer un nouveau descripteur de paragraphes } if ChainePara = nil then begin new(ChainePara); Para := ChainePara; Para^.Preced := nil; end else begin new(Para^.Suivant); Para^.Suivant^.Preced := Para; Para := Para^.Suivant; end; Para^.Suivant := nil; Para^.Debut := L; NotDone := true; { maintenant, cherche la fin du bloc de lignes non vides } while NotDone do begin P := P^.LigneSuivante; L := L+1; if P=nil then NotDone := false else NotDone := P^.Texte'' end; { while } Para^.Fin := L-1; end; { if } until P = nil; end; { Paragraphes }

http://cuisung.unige.ch/std/ex/7/4f.txt [23-09-2001 16:31:54]

http://cuisung.unige.ch/std/ex/7/1a.txt

procedure Insertion( Valeur, NumChaine : integer); {Procedure permettant d'affecter une valeur a la liste qui se trouvre a NumChaine dans le tableau} var Courant,Entete: PtrNoeud; begin if (NumChaine> MaxNbSommets) OR (NumChaine < 1) then begin writeln('L''indice du tableau doit etre entre 1 et ', MaxNbSommets); readln; halt end else begin {Creation du noeud a inserer} New(Entete); with Entete^ do begin Donnee:= Valeur; Suivant:= nil; end; { with } if TabElement[NumChaine].Chaine = NIL then TabElement[NumChaine].Chaine:= Entete else begin Courant:= TabElement[NumChaine].Chaine; while Courant^.SuivantNIL DO Courant:= Courant^.Suivant; {Insertion de Entete dans Courant} Courant^.Suivant := Entete; end; { if TabElement... else } TabElement[NumChaine].Taillechaine := succ(TabElement[NumChaine].Taillechaine); end; { if (NumChaine> MaxNbSommets)... else } end; { Insertion } Procedure afficher; {Parcourir la Chaine et afficher le contenu de la Chaine} var j: integer; PtCourant: PtrNoeud; begin { afficher } for j:= 1 to MaxNumChaine do begin writeln('TabElement[',j,']'); PtCourant:= TabElement[j].Chaine; while PtCourant nil do begin writeln(PtCourant^.Donnee); PtCourant:= PtCourant^.Suivant; end; { while } readln; end; { for } end; { afficher }

http://cuisung.unige.ch/std/ex/7/1a.txt [23-09-2001 16:32:13]

http://cuisung.unige.ch/std/ex/7/4g.txt

Procedure ChercherInsertion(Valeur: Integer; VAR NoeudInsertion: PtrNoeud); {Permet de determiner le noeud d'insertion pour la valeur donnee: NoeudInsertion retourne NIL, si Valeur existe deja dans l' anneau} Var Courant: PtrNoeud; begin Courant:= Entete^.Suivant; while (Courant Entete) and (Courant^.Donnee < Valeur) do Courant:= Courant^.Suivant; if Courant = Entete then NoeudInsertion:= Courant^.Precedent else {Courant^.Donnee >= Valeur} if Courant^.Donnee = Valeur then NoeudInsertion := NIL else NoeudInsertion := Courant^.Precedent; end; {Chercher Insertion} Procedure RangerValeur(Valeur: Integer); {Permet de ranger une valeur donnee dans l'anneau trié} VAR NInsertion, Nouveau : PtrNoeud; begin AnneauVide := False; New(Nouveau); Nouveau^.Donnee:= Valeur; if Entete=nil then InsererNoeud(Nouveau,Entete) else begin ChercherInsertion(Valeur, NInsertion); if (NInsertion = Entete) and (Entete^.Donnee < Valeur) then Entete := Nouveau; {On changera l'entete si la valeur donnee est plus grande que celle de l'entete} if NInsertion NIL then InsererNoeud(Nouveau,NInsertion) else writeln('Cette Valeur existe deja dans la liste'); end; { if Entete=nil ... else } end;{RangerValeur}

http://cuisung.unige.ch/std/ex/7/4g.txt [23-09-2001 16:32:46]

http://cuisung.unige.ch/std/ex/8/1c.txt

a) Arbre('-', Arbre('*', Arbre('-', Feuille('a'), Arbre('+', Feuille('b'), Feuille('c') ) ), Feuille('d') ), Arbre('/', Arbre('-', Feuille('e'), Feuille('f') ), Arbre('*', Feuille('g'), Feuille('h') ) ) ) b) type Noeud = record Operateur: char; G, D: PtrNoeud; end; { Noeud } function Feuille(Contenu: char): PtrNoeud; var P: PtrNoeud; begin new(P); with P^ do begin Operateur := Contenu; G := nil; D := nil; end; {with} Feuille:=P; end; { Feuille } function Arbre(Contenu: char; Gauche, Droit: PtrNoeud): PtrNoeud; var P: PtrNoeud; begin new(P); with P^ do begin Operateur := Contenu; G := Gauche; D := Droit; end; {with} Arbre:=P; end; { Arbre }

http://cuisung.unige.ch/std/ex/8/1c.txt [23-09-2001 16:33:07]

http://cuisung.unige.ch/std/ex/10/3a.sol.txt

procedure DFS( LeGraphe: Graphe); var CmptrVisite, IndexSommet : 0..MaxNbSommets; NumeroDOrdre: array[1..MaxNbSommets] of integer; procedure Visite (IndexSommet : integer); var Voisins: SerieDeSommets; Voisin: integer; begin CmptrVisite := CmptrVisite + 1; NumeroDOrdre[IndexSommet]:=CmptrVisite; write(NomSommet(IndexSommet,LeGraphe), ' '); Voisins := SommetsVoisins(IndexSommet,LeGraphe); Voisin := 0; if not FinDeSerie(Voisins) then begin repeat if Voisin=0 then Voisin := PremierSommet(Voisins) else Voisin := SommetSuivant(Voisins); if NumeroDOrdre[Voisin]=0 then Visite (Voisin); until FinDeSerie(Voisins); end; { if not FinDeSerie } end; { Visite } begin { DFS } CmptrVisite := 0; for IndexSommet:= 1 to NombreDeSommets(LeGraphe: Graphe) do NumeroDOrdre[IndexSommet]:=0; for IndexSommet := 1 to NombreDeSommets(LeGraphe: Graphe) do if NumeroDOrdre[IndexSommet] = 0 then Visite (IndexSommet) end; { DFS }

http://cuisung.unige.ch/std/ex/10/3a.sol.txt [23-09-2001 16:33:39]

http://cuisung.unige.ch/std/ex/10/4a.sol.txt

procedure Imprime(LeDico: VersNoeud); const TailleFile = 100; type Objet=record Mot: String80; Place: VersNoeud; end; { Objet } FileCirculaire=record Element: array[0..TailleFile] of Objet; IndexIn, IndexOut: 0..TailleFile; Plein:boolean; end; { FileCirculaire } var MaFile: FileCirculaire; Obj: Objet; procedure Avance(N: VersNoeud; S: String80); var c:char; Splus:String80; l: integer; O: Objet; begin { Avance } if N^.Complet then writeln(S); Splus := S; l := length(Splus)+1; Insert(' ',Splus, l); for c := 'a' to 'z' do if N^.Desc[c]nil then begin Splus[l] := c; O.Mot := Splus; O.Place := N^.Desc[c]; Met(MaFile, O); end; { if N^.Desc[c]nil } end; { Avance } begin { Imprime } MaFile.IndexIn := 0; MaFile.IndexOut := 0; MaFile.Plein := false; if LeDiconil then Avance(LeDico, ''); while not Vide(MaFile) do begin Ote(MaFile, Obj); Avance(Obj.Place, Obj.Mot); end; {while} end; { Imprime }

http://cuisung.unige.ch/std/ex/10/4a.sol.txt [23-09-2001 16:33:54]

Structuration des Données Informatiques - 13.4, solution 1

indice du tableau

chaîne associée valeur entre () = H2(Mot)

0 1 2 3 4 5 6 7 8 9 10

a (4)->du (12)->quatre (16) sont (7)->premier (14) aurait (2)->un (9)->lesquels (17) cycle (2) les (8)->atteint (12)->y (13) oral (1)->le (7) examens (5)->pour (10) n (5)->examen(6) si (6)->admis(13) note (2)->chaque (17)->qu (22) subir (3)

http://cuisung.unige.ch/std/ex/13/4a.sol.html [23-09-2001 16:34:06]

http://cuisung.unige.ch/std/ex/15/1a.sol.txt

procedure Extension(Entree: TableDecision; var Sortie: TableDecision); var Regle: 0..MaxNbRegles; Condition, Cond: 0..MaxNbCond; Action: 0..MaxNbActions; begin { Extension } Sortie.NbConditions := Entree.NbConditions; Sortie.NbRegles := Entree.NbRegles; Sortie.NbActions := Entree.NbActions; for Regle := 1 to Entree.NbRegles do begin for Condition := 1 to Entree.NbConditions do Sortie.ValCond[Regle,Condition] := Entree.ValCond[Regle,Condition]; for Action := 1 to Entree.NbActions do Sortie.Agir[Regle,Action] := Entree.Agir[Regle,Action]; end; { for } Regle := 1; while Regle -1 -> 2 -> -1 -> -3 produira la séquence 3->-1->2->-3->-1->... qui se répète à l'infini.

http://cuisung.unige.ch/std/ex/7/4e.sol.html [23-09-2001 16:34:53]

Solution de l'exercice 2, chapître 8 section 2

1)

http://cuisung.unige.ch/std/ex/8/2b.sol.html (1 of 2) [23-09-2001 16:35:40]

Solution de l'exercice 2, chapître 8 section 2

2) procedure ImprimePetitsEnfants(LaPersonne: PersonnePtr); var CourantEnfant, CourantPetitEnfant: ChaineFreresSoeurs; begin if (LaPersonne = nil) then writeln('Erreur: pointeur nil passe a la procedure ImprimePetitsEnfants') else begin {trouve le NoeudFrereSoeur de son premier enfant} CourantEnfant := LaPersonne^.Enfants; while (CourantEnfant nil) do begin {trouve le NoeudFrereSoeur de son premier petit-enfant. Note: Il faut utiliser le champ FrereOuSoeur pour acceder au pointeur de type PersonnePtr} CourantPetitEnfant := CourantEnfant^.FrereOuSoeur^.Enfants; while (CourantPetitEnfant nil) do begin write(CourantPetitEnfant^.FrereOuSoeur^.Nom,', '); writeln(CourantPetitEnfant^.FrereOuSoeur^.Prenom); CourantPetitEnfant := CourantPetitEnfant^.FrereSoeurSuivant; end; {while (CourantPetitEnfant nil)} CourantEnfant := CourantEnfant^.FrereSoeurSuivant; end; {while (CourantEnfant nil)} end; {else} end; {ImprimePetitsEnfants}

http://cuisung.unige.ch/std/ex/8/2b.sol.html (2 of 2) [23-09-2001 16:35:40]

Structuration des Données Informatiques - 14.3, solution 2

a) La page racine étant déjà pleine, l'adjonction de la valeur 10 va nécessiter la scission de cette page en deux et la création d'une page au niveau au-dessus contenant l'élément charnière (qui est 10). Le B-arbre résultant est:

b) La page dans laquelle devrait venir la nouvelle valeur (21) est déjà pleine. La page de même niveau qui est à sa gauche peut recevoir un élément supplémentaire. L'élément intermédiaire (20) qui se trouve dans le niveau au dessus est donc déplacé dans la page de gauche et la place ainsi libérée peut être occupée par le plus petit élément de la page excédentaire. Le B-arbre résultant est:

c) En supprimant la valeur 55, la page en question tombe en dessous du nombre minimum d'éléments. La page d'à côté ayant plus que le minimum d'éléments, on peut lui emprunter un élément (42) qui vient remplacer l'élément intermédiaire (50) qui se trouve dans le niveau au dessus. Cet élément intermédiaire (50) vient alors dans la page dans laquelle il manquait un élément. Le B-arbre résultant est:

d) La page dans laquelle devrait venir la nouvelle valeur (23) est déjà pleine. Les deux pages voisines de même niveau sont aussi pleines. Il faut donc scinder la page excédentaire en deux, avec comme élément charnière la valeur 23 qui ira dans la page du niveau au-dessus. Les deux pages résultant de la scission seront connectées à l'élément charnière nouvellement rajouté au niveau au-dessus. Le B-arbre résultant est:

e) La page dans laquelle devrait venir la nouvelle valeur (4) est déjà pleine. La page voisine de même niveau est aussi pleine. Il faut donc scinder la page excédentaire en deux, avec comme élément charnière la valeur 4 qui ira dans la page du niveau au-dessus. Les deux pages résultant de la scission seront connectées à l'élément charnière nouvellement rajouté au niveau au-dessus. Le B-arbre résultant est:

http://cuisung.unige.ch/std/ex/14/3b.sol.html (1 of 2) [23-09-2001 16:37:08]

Structuration des Données Informatiques - 14.3, solution 2

f) Pour supprimer la valeur 15, on va d'abord l'échanger avec la valeur qui se trouve le plus à droite du sous-arbre gauche, en l'occurence la valeur 7. La valeur 7 remplace donc la valeur 15 dans la page racine et doit être supprimée de la feuille dans laquelle elle se trouvait précédemment. Cette page feuille ayant assez d'éléments, la suppression peut se faire sans autre. Le B-arbre résultant est:

http://cuisung.unige.ch/std/ex/14/3b.sol.html (2 of 2) [23-09-2001 16:37:08]

http://cuisung.unige.ch/std/ex/7/4c.txt

procedure EffaceLigne(var UnTexte: VersLigne; NumeroLigne: integer); var courant: VersLigne; i: integer; begin if NumeroLigne < 1 then writeln ('NumeroLigne doit etre >= 1') else begin courant := UnTexte; i := 1; while (courantnil) and (i < NumeroLigne) do begin courant := courant^.LigneSuivante; i := i+1; end; (* while *) if courant=nil then writeln('La chaine est trop courte') else begin with courant^ do begin if courant = UnTexte then UnTexte := LigneSuivante else LignePrecedente^.LigneSuivante := LigneSuivante; if LigneSuivante nil then LigneSuivante^.LignePrecedente := LignePrecedente; end; (* with *) dispose(courant); end; (* if courant=nil *) end; (* if NumeroLigne < 1 *) end; (* EffaceLigne *) procedure JoindreLignes(var UnTexte: VersLigne; LigneCourante: integer); var courant, LigneADetruire: VersLigne; i: integer; begin if LigneCourante < 1 then writeln ('LigneCourante doit etre >= 1') else begin courant := UnTexte; i := 1; while (courantnil) and (i < LigneCourante) do begin courant := courant^.LigneSuivante; i := i+1; end; (* while *) if courant=nil then writeln('La chaine est trop courte') else if courant^.LigneSuivante = nil then writeln('On est sur la derniere ligne') else begin with courant^ do begin Texte := concat(Texte, LigneSuivante^.Texte); if LigneSuivante^.LigneSuivante = nil then dispose(LigneSuivante) else begin LigneSuivante^.LigneSuivante^.LignePrecedente := courant; LigneADetruire := LigneSuivante; LigneSuivante := LigneSuivante^.LigneSuivante; end; (* if LigneSuivante... *) end; (* with *) dispose(LigneADetruire); end; (* if courant^.LigneSuivante = nil *) end; (* if LigneCourante < 1 *) end; (* JoindreLignes *)

http://cuisung.unige.ch/std/ex/7/4c.txt [23-09-2001 16:37:37]

Structuration des Données Informatiques - 14.2, solution 1

a) Etant donné qu'un bloc de données dispose de 1536 octets et qu'une donnée occupe 76 octets, il peut y avoir au plus 20 données par bloc (1536 div 76=20 et restent 16 octets qui peuvent être utilisés pour pointer vers le bloc suivant et vers un eventuel bloc de débordement). Du fait que les blocs ne sont initialement remplis qu'à 80%, il n'y aura que 16 données par bloc (20*80/100 = 16). Il faudra donc 62'500 blocs de données pour stocker 1'000'000 éléments (1'000'000/16 = 62'500). Pour ce qui est des blocs d'index, chaque élément du bloc est composé d'une clé de 8 octets et d'une référence de 4 octets, soit 12 octets par élément. Il y a donc 85 éléments par bloc d'index (1024 div 12 = 85, reste 4). La première couche de blocs d'index, qui pointent vers des blocs de données, doit contenir un élément par bloc de données. Il y a donc 736 blocs (62'500 div 85 = 735, reste 25; c'est-à-dire qu'il y a 735 blocs entièrement pleins et le dernier bloc ne contenant que 25 éléments). La deuxième couche de blocs d'index occupe 9 blocs (736 div 85 = 8, reste 56 -> 8 blocs pleins et le neuvième avec 56 éléments). La troisième et dernière couche de blocs d'index ne contient qu'un seul bloc, avec seulement 9 éléments sur 85 occupés. La taille de l'espace disque occupé est donc: (nombre de blocs de données*taille d'un bloc de données) + (nombre de blocs d'index*taille d'un bloc d'index) = 62'500*1536 + (736+9+1)*1024 = 96'763'904 octets. En résumé: ❍ nombre de blocs de données = 62'500 ❍ profondeur de l'arborescence d'index = 3 ❍ nombre de blocs d'index = 736 puis 9 puis 1 ❍ espace disque occupé = 96'763'904 b) Etant donné qu'une page du B-arbre dispose de 1024 octets et qu'il faut stocker une référence de plus que de données, en supposant que l'on utilise 2 octets pour stocker le nombre d'éléments effectifs dans la page, il peut y avoir ((1024-4-2) div (76+4) = 12, reste 58 octets inutilisés). Le B-arbre est donc d'ordre 6. Si l'on suppose que toutes les pages sont pleines, 1'000'000 éléments occuperaient alors 83'334 pages (1'000'000 div 12 = 83'333, reste 4 éléments qui vont occuper partiellement la 83'334ème page). Si, à l'autre extrème, l'on suppose que les pages ne sont qu'à moitié pleines, 1'000'000 éléments occuperont alors 166'667 pages (1'000'000 div 6 = 166'666, reste 4 éléments qui vont occuper une page de plus). L'espace disque nécessaire sera donc compris entre 85'334'016 octets (83'334*1024) et 170'667'008 octets (166'667*1024). Pour ce qui est du nombre de niveaux de l'arborescence, il faut là aussi envisager les 2 cas http://cuisung.unige.ch/std/ex/14/2a.sol.html (1 of 2) [23-09-2001 16:38:00]

Structuration des Données Informatiques - 14.2, solution 1

extrèmes de pages toutes entièrement pleines ou toutes à moitié pleines: ❍ Quand les pages sont entièrement pleines, chaque page a 13 descendants. On peut facilement calculer le nombre de pages à chaque niveau puisque ce sont les puissances successives de 13: 1, 13, 169, 2197, 28561, 371'293. On voit alors facilement qu'il faut 6 niveaux pour avoir les 83'334 pages nécessaires pour stocker les 1'000'000 éléments. ❍ Dans le cas le plus défavorable où la racine ne contient qu'un seul élément (et deux descendants) et toutes les autres pages 6 éléments (et 7 descendants), les niveaux successifs contiennent: 1, 2, 14, 98, 686, 4802, 16'807 et, finalement 235'298 pages. Cela correspond à 2*7n-2 pages pour le niveau n. On voit donc qu'il faut 8 niveaux dans ce cas. En résumé: ❍ nombre de pages: entre 83'334 et 166'667 ❍ espace disque: entre 85'334'016 et 170'667'008 octets ❍ niveaux: entre 6 et 8.

http://cuisung.unige.ch/std/ex/14/2a.sol.html (2 of 2) [23-09-2001 16:38:00]

Structuration des Données Informatiques - 11.3, solution 2

1. Comme il s'agit d'un graphe pondéré, il faudra une matrice d'entiers pour représenter les arcs et une autre structure pour représenter les sommets, par exemple un tableau de strings. En supposant que les sommets sont rangés dans le tableau dans l'ordre suivant: ['Bern', 'Genève', 'Lausanne', 'Lucerne', 'Lugano', 'Milan', 'Neuchâtel', 'Zürich'], la matrice de pondération pourrait être ainsi (l'absence d'arc est notée -1): 0 -1 96 92 -1 -1 -1 120 -1 0 60 -1 -1 325 -1 -1 96 60 0 -1 -1 -1 68 -1 92 -1 -1 0 174 -1 -1 -1 -1 -1 -1 174 0 78 -1 206 -1 325 -1 -1 78 0 -1 -1 -1 -1 68 -1 -1 -1 0 -1 120 -1 -1 -1 206 -1 -1 0 2. Les déclarations Pascal pourraient être: var Distance:array[1..MaxNbSommets,1..MaxNbSommets] of integer; Villes: array[1..MaxNbSommets] of string; NbSommets: integer; 3. Une possibilité est de calculer le graphe de fermeture transitive indiquant la longueur du plus court chemin entre deux sommets (en utilsant une variante de l'algorithme de Warshall): for y:= 1 to NbSommets do for x:= 1 to NbSommets do if Distance[x,y] > -1 then for j:= 1 to NbSommets do if Distance[y,j] > -1 then if (Distance[x,j] > (Distance[x,y]+Distance[y,j])) or (Distance[x,j] = -1) then Distance[x,j] := Distance[x,y]+Distance[y,j]; Après quoi, la fonction pour déterminer la distance minimale entre deux villes x et y n'aura qu'à retourner Distance[index(x),index(y)]: function MinDist(Ville1, Ville2: string): integer; { accès à la matrice de fermeture transitive "Distance" par effet de bord. Retourne la plus courte distance entre Ville1 et Ville2. Retourne -1 s'il n'y a pas de chemin entre Ville1 et Ville2. } begin MinDist := Distance[index(Ville1),index(Ville2)]; end; { MinDist } =================================================================== Une autre possibilité consiste à reprendre l'algorithme de DFS et à ajouter des paramètres à la procédure Visite pour conserver la longueur du chemin partiel et retourner la distance minimale quand on a atteind le noeud de destination (on pourrait utiliser le BFS, mais cela impliquerait de mémoriser la longueur de tous les chemins partiels pour effectuer la comparaison à l'arrivée):

http://cuisung.unige.ch/std/ex/11/3b.sol.html (1 of 2) [23-09-2001 16:38:44]

Structuration des Données Informatiques - 11.3, solution 2

function MinDist(Ville1, Ville2: string): integer; { accès à la matrice "Distance" par effet de bord. Retourne la plus courte distance entre Ville1 et Ville2. Retourne MaxInt s'il n'y a pas de chemin entre Ville1 et Ville2. } var DistMin, i, Index2: integer; Parcouru: array[1..MaxNbSommets] of boolean; procedure Visite (IndexSommet : integer; DistPartielle:integer; var DistMin: integer); var AutreSommet : integer; begin if IndexSommet=Index2 then begin { on est arrivé à destination. Par un chemin plus court qu'avant? } if DistPartielle < DistMin then DistMin := DistPartielle end else begin Parcouru[IndexSommet]:=true; { marque par où on passe } for AutreSommet := 1 to NbSommets do { Y a-t-il un arc vers AutreSommet et pas de cycle? } if (Distance[IndexSommet,AutreSommet] > 0) and not Parcouru[AutreSommet] then Visite(AutreSommet, DistPartielle+Distance[IndexSommet,AutreSommet], DistMin); { ôte la marque en rebroussant chemin pour pouvoir repasser par ce même noeud par un autre chemin } Parcouru[IndexSommet]:=false; end; { if } end; { Visite } begin { MinDist } for i := 1 to NbSommets do Parcouru[i]:= false; Index2 := index(Ville2); DistMin := MaxInt; Visite(index(Ville1), 0, DistMin); MinDist := DistMin; end; { MinDist } Le bût du tableau Parcouru est d'éviter de boucler dans des cycles, en marquant chaque noeud par lequel on passe. On enlève la marque dès que l'on fait marche arrière pour permettre à l'algorithme de repasser éventuellement par ce même noeud, au cas où celui-ci se trouverait le long d'un autre chemin qui serait plus court.

http://cuisung.unige.ch/std/ex/11/3b.sol.html (2 of 2) [23-09-2001 16:38:44]

http://cuisung.unige.ch/std/ex/7/4a.txt

procedure DeplacerDansAnneau(UnAnneau: Anneau; var Arret: TypeArret; Depl: integer); var i : integer; pointeur : Anneau; { pointe normalement sur l'elem. qui serait detruit si Depl=1} ALaFin, { sera vrai si on detruit l'elem. en derniere position de l'anneau } PasFini : boolean; procedure Supprime(var Courant : Anneau; var ALaFin: boolean); {procedure pour supprimer un element de l'anneau et ajuster le pointeur "Courant" en consequence. Si on detruit le permier element, ajuste UnAnneau en consequence. ALaFin sera vrai si on est en train de detruire le dernier element. } var temp : Anneau; begin {1} if Courant^.predecesseur = Courant then begin {2} { on detruit l'unique element restant } dispose(Courant); UnAnneau := nil; end {2} { if ... then } else begin {3} {on efface l'element de l'anneau} Courant^.predecesseur^.successeur := Courant^.successeur; Courant^.successeur^.predecesseur := Courant^.predecesseur; ALaFin := Courant^.successeur=UnAnneau; temp := Courant; {on ajuste le pointeur} Courant := Courant^.successeur; {si on detruit le 1er elem., ajuster "UnAnneau" } if temp=UnAnneau then UnAnneau := Courant; {on efface physiquement l'element} dispose(temp); end; {3} { if ... else } end; {1} { Supprime }

http://cuisung.unige.ch/std/ex/7/4a.txt (1 of 2) [23-09-2001 16:39:11]

http://cuisung.unige.ch/std/ex/7/4a.txt

begin {4} { DeplacerDansAnneau } PasFini := UnAnneaunil; Arret := AnneauVide; ALaFin := false; pointeur := UnAnneau; while PasFini do begin {5} {si le deplacement est nul, on s'arrete} if Depl = 0 then begin {6} Arret := ElementNul; PasFini := false; end {6} { if ... then } else if Depl > 0 then begin {7} {si le deplacement est positif et on est a la fin, on s'arrete } if ALaFin then begin {8} PasFini := false; Arret := SortieAnneau; end {8} { if ALaFin then } else begin {9} {si le deplacement est positif} i := 1; while i < Depl do begin {10} {on se deplace} pointeur := pointeur^.successeur; {on verifie qu'on sort pas de l'anneau} if pointeur = UnAnneau then begin {11} Arret := SortieAnneau; i := Depl; PasFini := false; end {11} { if then } else i := i+1; end; {10} { while } end {9} { If ALaFin ... else } end {7} { if Depl > 0 } else begin {12} {de meme, pour le cas ou le deplacement est negatif} i := 0; while i > Depl do begin {13} { on veut reculer d'un cran, a moins d'etre au debut } if (pointeur=UnAnneau) and not ALaFin then begin {14} Arret := SortieAnneau; i := Depl; PasFini := false; end {14} { if } else begin {15} pointeur := pointeur^.predecesseur; i := i-1; end; {15} { if ... else } end; {13} { while } end; {12} { if ... else } if PasFini then begin {16} {on prend la nouvelle valeur pour le deplacement et on l'imprime} Depl := pointeur^.Entier; writeln(pointeur^.Entier); {on supprime l'element de l'anneau } Supprime(pointeur, ALaFin); {si l'anneau est vide apres cette suppression, il faudra s'arreter} PasFini := pointeur nil; end; {16} { if PasFini } end; {5} { while PasFini } end; {4} { DeplacerDansAnneau }

http://cuisung.unige.ch/std/ex/7/4a.txt (2 of 2) [23-09-2001 16:39:11]

Structuration des Données Informatiques - 8.1, solution 1

Il y a bien entendu beaucoup de solutions possibles. Le tout est de ne pas mettre un descendant avant un de ses ancêtres. On peut donc envisager de sérialiser les données de l'arbre, une ligne après l'autre, de la racine vers les feuilles: a) 20 18 42 3 26 14 39 7 30 10 34 b) vos beaux yeux amour marquise d mourir font me On aurait pu aussi imaginer faire un parcours en pré-ordre de l'arbre...

http://cuisung.unige.ch/std/ex/8/1a.sol.html [23-09-2001 16:39:35]

http://cuisung.unige.ch/std/ex/11/5a.txt

procedure TriTopoInverse(LeGraphe: Graphe); const MaxNbSommets=20; var i, CmptrVisite, IndexSommet : 0..MaxNbSommets; NumDOrdre : array[1..MaxNbSommets] of integer; Parcouru:array[1..MaxNbSommets] of boolean; NbSommets: integer; procedure Visite (IndexSommet : integer); var AutreSommet : integer; Voisins: SerieDeSommets; begin CmptrVisite := CmptrVisite + 1; NumDOrdre[IndexSommet] := CmptrVisite; Parcouru[IndexSommet] := true; Voisins := SommetsVoisins(IndexSommet, LeGraphe); if not FinDeSerie(Voisins) then begin AutreSommet := PremierSommet(Voisins); repeat if Parcouru[AutreSommet] then writeln(NomSommet(AutreSommet,LeGraphe), ' fait partie d''un cycle') else if NumDOrdre[AutreSommet] = 0 then Visite (AutreSommet); if FinDeSerie(Voisins) then AutreSommet := 0 else AutreSommet := SommetSuivant(Voisins); until AutreSommet = 0; end; { if } Parcouru[IndexSommet] := false; write(NomSommet(IndexSommet,LeGraphe)); end; { Visite } begin { TriTopoInverse } NbSommets := NombreDeSommets(LeGraphe); CmptrVisite := 0; for IndexSommet := 1 to NbSommets do NumDOrdre[IndexSommet]:=0; for IndexSommet := 1 to NbSommets do if NumDOrdre[IndexSommet]=0 then begin for i := 1 to NbSommets do Parcouru[i] := false; Visite (IndexSommet); end; { if } end; { TriTopoInverse }

http://cuisung.unige.ch/std/ex/11/5a.txt [23-09-2001 16:39:49]

Structuration des Données Informatiques - 14.3, solution 1

Le B-arbre résultant est:

Pour y arriver, on passe par les étapes suivantes: ● En supprimant g, on se trouve dans la situation suivante qui va nécessiter de fusionner la page où se trouvait g avec sa voisine de gauche et l'élément charnière du niveau au-dessus:





En effet, la page où se trouvait g est tombée en dessous du seuil minimum et la page voisine est au seuil minimum. On ne peut donc pas lui "emprunter" d'élément. On aboutit donc à la situation suivante, où la page qui contenait g doit être supprimée et la page du niveau au-dessus est tombée en dessous du seuil minimum et doit fusionner avec sa voisine de droite puisque celle-ci est au seuil minimum:

On aboutit ainsi à la situation finale, où la page qui contenait q ainsi que la page racine doivent être supprimées.

http://cuisung.unige.ch/std/ex/14/3a.sol.html [23-09-2001 16:40:12]

http://cuisung.unige.ch/std/ex/7/4b.txt

type VersMaillon = ^Maillon; Maillon = record Precedent, Suivant: VersMaillon; Contenu: integer; Visite: boolean; end; { Maillon } Arrets = (SortieChaine, Cycle); procedure Deplacement(LaChaine: VersMaillon; PremierSaut: integer; var TypeArret: Arrets; var PositionArret: integer); var Courant: VersMaillon; Deplace, Tmp: integer; begin PositionArret := 1; Deplace := PremierSaut-1; Courant := LaChaine; while Courant nil do begin Courant^.Visite := false; Courant := Courant^.Suivant; end; { while } Courant := LaChaine; while Deplace 0 do begin Tmp := Deplace; while ((Deplace < 0) and (Courant^.Precedent nil)) or ((Deplace > 0) and (Courant^.Suivant nil)) do if Deplace > 0 then begin Courant := Courant^.Suivant; Deplace := Deplace-1; end else begin Courant := Courant^.Precedent; Deplace := Deplace+1; end; if Deplace 0 then begin TypeArret := SortieChaine; Deplace := 0; end else if Courant^.Visite then begin TypeArret := Cycle; Deplace := 0; end else begin PositionArret := PositionArret + Tmp; Deplace := Courant^.Contenu; Courant^.Visite := true; end; {if } end; { while } end; { Deplacement }

http://cuisung.unige.ch/std/ex/7/4b.txt [23-09-2001 16:40:36]

http://cuisung.unige.ch/std/ex/8/2a.txt

type VersNoeud= ^Noeud; Noeud= record Desc: array['a'..'z'] of VersNoeud; Complet: boolean; end; { Noeud } var Dico: VersNoeud; function Trouve(LeDico: VersNoeud; LeMot: string) : boolean; begin { Trouve } if LeDico=nil then Trouve := false else if LeMot = '' then Trouve := LeDico^.Complet else Trouve := Trouve(LeDico^.Desc[LeMot[1]], copy(LeMot,2,length(LeMot)-1)); end; { Trouve } { version non-recursive } function Trouve(LeDico: VersNoeud; LeMot: string) : boolean; var i: integer; Courant: VersNoeud; begin { Trouve } i:=1; Courant := LeDico; while (i
View more...

Comments

Copyright ©2017 KUPDF Inc.
SUPPORT KUPDF