1/4 Structures de données Gilles Falquet, semestre d’été 2000 1 Données numériques (2pts) 1.1 Nombres entiers Dans une application on utilise deux types de nombres entiers T1 et T2. Les T1 sont codés sur 6 bits et les T2 sur 8 bits, avec la technique du complément à 2 pour représenter les nombres négatifs. a) Quel est le plus grand, respectivement le plus petit, entier qu’on preut représenter avec le type T1 et avec le type T2 ? b) Si a est une variable de type T1 et b une variable de type T2, combien faut-il prévoir de bits au minimum pour représenter de manière exacte le résultat de l’opération a + b. c) Même question, si l’on veut représenter le résultat de la multiplication a × b. 1.2 Nombres flottants On considère le type flottant float tel qu’il est défini dans Java (norme IEEE 754: représentation sur 32 bits). a) Pour chacun des nombres ci-dessous, dites s’il peut ou non être représenté de manière exacte avec une variable de type float. • 2 • 3.5 • 0.111 • 51456 • 67892345627 • 0.015625 ( = 2–6) • 0.0001220703125 (= 2–13) • 3 × 10–19 b) Que vaudront rp, rm, rf, rd (approximativement) après l’exécution de cette séquence d’instructions ? float a = 1.0f; (le suffixe f indique qu’il s’agit d’un nombre de type float) float b = 0.0000000000001f; rp = a + b; rm = a - b; rf = a * b; rd = a / b; Structures de données septembre 2000 2/4 2 Types abstraits algébriques (1.5pts) Dans un jeu les pièces sont placées sur des cases numérotées 1, 2, 3, etc. Les joueurs peuvent placer des pièces sur des cases ou les en enlever. La spécification qui suit définit l’évolution de l’état du jeu (représenté par la sorte jeu) en fonction des mouvements des pièces (de la sorte piece). SPECIFICATION Jeu UTILISE Entier, Booléen; SORTES jeu, pièce; OPERATIONS -- constructeurs vide : -> jeu placer : pièce, entier, jeu -> jeu enlever : pièce, jeu -> jeu -- sélecteur position : pièce, jeu -> entier nombre-pieces : entier, jeu -> entier AXIOMES POUR TOUT P, Q, X, J 1. position(P, vide) == 0; 2. position(P, placer(Q, X, J)) == si P == Q alors X sinon position(P, J); 3. position(P, enlever(Q, J)) == si P == Q alors 0 sinon position(P, J); 4. nombre-pieces(X, vide) == 0; 5. nombre-pieces(X, placer(P, Y, J) == si X == Y alors 1 + nombre-pieces(X, J) sinon nombre-pieces(X, J) 6. nombre-pieces(X, enlever(P, J) == si position(P, J) == X alors nombre-pieces(X, J) - 1 sinon nombre-pieces(X, J) Appliquez les axiomes (et uniquement les axiomes!) pour simplifier au maximum les expressions ci-dessous, écrivez les principales étapes de la simplification. a) b) c) d) e) f) g) h) position(a, vide). nombre-pieces(3, vide). position(a, placer(a, 14, placer(b, 33, placer(c, 22, vide)))). position(b, placer(a, 4, placer(b, 4, placer(a, 6, vide)))). nombre-pieces(4, placer(a, 4, placer(b, 6, placer(c, 4, vide))) position(b, enlever(c, enlever(d, placer(b, 6, enlever(b, vide))))). nombre-pieces(21, placer(b, 21, enlever(a, placer(c, 17, placer(a, 21, placer(d, 21, vide)))))) nombre-pieces(6, placer(a, 6, placer(a, 6, placer(a, 6, vide)))) Structures de données septembre 2000 3/4 3 Listes (2pts) On part d’une liste dont certains éléments sont peuvent être répétés plusieurs fois de suite. Le but est d’obtenir deux listes de même taille : dans la première on aura les mêmes éléments que dans la liste de départ mais sans les répétitions, dans la seconde on aura le nombre d’occurence de l’élément correspondant de la première liste. Par exemple, si on part de la liste [w, w, w, c, k, k, k, k, h, h, t, w, w, m, c, c, c] on devra obtenir les deux listes [w, c, k, h, t, w, m, c] [3, 1, 4, 2, 1, 2, 1, 3] Ecrivez un algortihme, sous forme d’une séquence d’instruction en Java ou pseudo-Java, qui réalise l’opération décrite ci-dessus. On suppose que la liste de départ se trouve dans une variable a de type Liste, les deux listes du resultats seront stockées dans des variables b et c de type Liste. La définition du type Liste est donnée ci-dessous. Attention: écrire un algorithme en pseudo-langage ne signifie pas écrire un texte vague. Votre algorithme doit être écrit très précisément et être facilement transposable dans un vrai langage de programmation (un texte en français n’est donc pas suffisant!). Définition du type Liste résultat opération paramètres effet Liste new Liste Liste insérer int i, T elem insère elem à la position i Liste remplacer int i, T elem remplace le i-ième élément par elem Liste supprimer int i supprime l’élément à la position i T element int i element se trouvant à la position i int longueur longueur de la liste boolean estVide la liste est-elle vide ? (longueur = 0) Structures de données crée une liste vide septembre 2000 4/4 4 Arbres (2pts) On a un arbre ternaire dont la structure est définie par le type Arbre ci-dessous : classe Arbre // variables d’instance Arbre enfant1, enfant2, enfant3 ; // si enfanti == null il n’y a pas de ie sous-arbre int valeur ; // valeur du noeud racine a) Ecrivez une méthode int somme() pour la classe Arbre qui fait un parcours en profondeur de l’arbre et calcule la somme de valeurs des noeuds. Vous pouvez écrire la méthode en Java ou en pseudo-Java (voir l’avertissement de la question précédente). b) On veut modifier un arbre de manière à mettre comme valeur de chaque noeud intérieur de l’arbre la somme des valeurs de ses enfants. La valeur des noeuds feuilles ne doit pas être modifiée. Ecrivez une méthode miseAJour() qui effectue ce traitement. Indication: basez-vous sur l’algorithme de parcours en profondeur car il faut d’abord faire le calcul pour les sous-arbres les plus « bas » avant de pouvoir mettre à jour la valeur des noeuds supérieurs. Exemple : -1 9 3 27 7 8 1 26 2 6 4 avant la mise à jour Structures de données 15 4 3 7 5 1 10 2 6 4 4 après la mise à jour septembre 2000