CSI 1502 Principes fondamentaux de conception de logiciels Chapitre 6: Tableaux de données
Objectifs d'apprentissage: Tableaux de données Comprendre comment faire les activités suivantes: Declarer et utiliser des tableaux de données Passer des tableaux de données et des éléments de tableaux de données comme paramètres Declarer et utiliser des tableaux d'objets Trier les éléments dans un tableau: Tri par sélection et tri par insertion Partie B: Après la semaine d'étude Tableaux à plusieurs dimensions La classe ArrayList Polygones et polylignes; types de bouton
Tableaux de données: Liste ordonnée de valeurs Le tableau en entier a un nom Chaque valeur a un index numérique 0 1 2 3 4 5 6 7 8 9 79 87 94 82 67 98 87 81 74 91 notes Un tableau de taille N est indexé de zéro à N-1 Ce tableau contient 10 valeurs qui sont indexées de 0 à 9
Tableaux de données (suite) On réfère à une valeur particulière dans le tableau à l'aide du nom du tableau suivi par l'index entre paranthèses carrées Par exemple, the expression notes[2] réfère à la valeur 94 (qui est la 3ieme valeur dans le tableau) Dans Java, le tableau est un objet Alors le nom du tableau est une variable référence à un objet, et le tableau doit être instancier
Exemples de tableaux notes[2] = 89; int premier = 5; notes[premier] = notes[premier] + 2; moyenne = (notes[0] + notes[9])/2; System.out.println ("Max = " + notes[5]);
Tableaux de données (suite) Un tableau contient plusieurs valeurs du même type Ce type peut être un type primitif ou une référence à object Alors, on peut créer un tableau d'entiers, ou un tableau de caractères, ou un tableau d'objets String, etc. Le tableau notes peut être déclaré comme suit int[] notes = new int[10];
Declarer des tableaux: Exemples float[] prix = new float[500]; boolean[] drapeaux; drapeaux = new boolean[20]; char[] codes = new char[1750];
Vérification de bornes: Vérification d'erreurs Lorsqu'un tableau est créé, il est de taille fixe Un index utilisé dans une référence de tableau doit spécifier un élément valide Voulant dire, l'index doit être dans les bornes (0 à N-1) L'interpréteur Java déclenche l'exception ArrayIndexOutOfBoundsException si l'index du tableau est hors des bornes Ceci est la vérification de bornes automatisée
Vérification de bornes: Un exemple Par exemple, si un tableau codes contient 100 valeurs, il peut seulement être indexé de 0 à 99 Si compteur a la valeur 100, alors la référence qui suit va déclencher une exception: System.out.println (codes[compteur]); Il est commun d'introduire des erreurs off-by-one quand on utilise des tableaux problême for (int index=0; index <= 100; index++) codes[index] = index*50 + epsilon;
Vérification de bornes : Utiliser length Chaque objet tableau a une constante publique appelée length qui stocke la taille du tableau Elle est référencée utilisant le nom du tableau (comme tout autre objet): notes.length Notez que length contient le nombre d'éléments, et non pas le plus grand index, i.e., la valeur de length est plus grand index + 1
Vérification de bornes: Extrait de ReverseOrder.java (p.325) { double[] numbers = new double[10]; System.out.println(“Size :” + numbers.length); for (int index = 0; index < numbers.length; index++) { System.out.println(“Enter number “ + (index + 1) + “ : “); numbers[index] = Keyboard.readDouble()); } // print in reverse order for (int index = numbers.length-1; index >= 0; index--) System.out.println(numbers[index] + “ “);
Syntaxe alternative pour la déclaration de tableau: Pas nécessaire! Les paranthèses carrées du type de tableau peuvent être associé au type d'élément ou au nom du tableau Alors les deux déclarations suivantes sont équivalentes: float[] prix; float prix[]; Le premier format est généralement plus lisible!!!
Listes d'initialisation: Affecter des valeurs Notez que lorsqu'on utilise une liste d'initialisation: l'opérateur new n'est pas utilisé la taille n'est pas spécifié La taille du tableau est déterminée par le nombre de valeurs dans la liste d'initialisation Une liste d'initialisation peut seulement être utilisé lors de la déclaration d'un tableau char[] letterGrades = {‘A’, ‘B’, ‘C’, ‘D’, ‘E’, ‘F’};
Listes d'initialisation : Extrait de Primes.java (p.330) … int[] primeNums = {2, 3, 5, 7, 11, 13, 17, 19}; System.out.println(“Array length :” + primeNums.length); System.out.println(“The first prime numbers”); for (int scan = 0; scan < primeNums.length; scan++) System.out.println(primeNums[scan] + “ “);
Utiliser les tableaux comme paramètres Un tableau en entier peut être passé comme paramètre à une méthode Comme tout autre objet, la référence au tableau est passée, qui a comme effet que les paramètres formels et actuels sont des alias Changer un élément dans le tableau à l'intérieur de la méthode va changer l'original Un élément de tableau peut être passé à une méthode aussi, mais suit les règles de passage de paramètres qui applique au type de cet élément
Utiliser les tableaux d'objets La déclaration suivante réserve de l'espace pour 25 références à des objets de type String String[] words = new String[25]; Mais ne crée pas les objets String comme tel Chaque objet stocké dans un tableau doit être instancié séparément Voir GradeRange.java (page 332)
Tableaux d'objets : Extrait de GradeRange.java (pp.332) … int[] cutoff = {95, 90, 87, 83, 80}; String[] grades = (‘A+’, ‘A’, ‘A-’, ‘B+’, ‘B’); for (int level = 0; level < cutoff.length; level++) System.out.println(grades[level] + “ “ + cutoff[level]); Output A+ 95 A 90 A- 87 B+ 83 B 80
Arguments de ligne de commande: A propos Main (finalement!) La signature de la méthode main indique qu'elle prend un tableau d'objets String comme paramètre Ces valeurs parviennent des arguments de ligne de commande qui sont fournit lorsque l'interpréteur est invoqué Par exemple, l'exécution de la commande suivante passe un tableau de trois objets String à main: > java DoIt pennsylvania texas california Ces chaînes de caractères sont stockées dans le paramètre aux indexes 0-2
A propos Main (String[] args): NameTag.java (p.334) public class NameTag { public static void main (String[] args) System.out.println(); System.out.println(“ “ + args[0]); System.out.println(“My name is “ + args[1]); } > java NameTag Hello Sue Hello My name is Sue > java NameTag Hello James My name is James
Utiliser les tableaux d'objets Des objets peuvent avoir des tableaux comme variables d'instance Alors, plusieurs structures utiles peuvent être créé avec des tableaux et des objets Le concepteur de logiciel doit déterminer soigneusement une organisation des données et des objets qui est applicable à la situation Voir CD Collection example, p.335, 337-338
Programme CD Collection: diagramme UML Tunes CDCollection - collection : CD[] - count: int - totalCost: double + main (args : String[]) : void 1 + addCD (title: String, artist: String, cost: double, tracks:int): void + toString( ): String - increaseSize(): void CD n - title : String - artist : String - cost : String - tracks : int + toString() : String
Exemple CD Collection: Tunes.java (Programme pilote) public class Tunes { public static void main (String[] args) { CDCollection music = new CDCollection(); music.addCD("So far so good", "Bryan Adams", 14.96, 14); music.addCD("Enrique", "Enrique Iglesias", 15.96, 13); System.out.println(music); } }
Exemple CD Collection: CDCollection.java public class CDCollection { private CD[] collection; private int count; private double totalCost; public CDCollection() // the constructor { collection = new CD[100]; count = 0; totalCost = 0.0; } //Adds a CD to the collection public void addCD(String title, String artist, double cost, int tracks) { if (count == collection.length) increaseSize(); collection[count] = new CD(title, artist, cost, tracks); totalCost += cost; count++; } Suite..
Exemple CD Collection: CDCollection.java (suite) // double the size of the collection private void increaseSize() { CD[] temp = new CD[collection.length * 2]; for (int cd = 0; cd < collection.length; cd++) temp[cd] = collection[cd]; collection = temp; } public String toString() { String report = " "; for (int cd = 0; cd < count; cd++) report += collection[cd].toString() + "\n"; return report; } }
Exemple CDCollection: CD.java public class CD { private String title, artist; private double cost; private int tracks; // The constructor public CD (String name, String singer, double price, int numTracks) { title = name; artist = singer; cost = price; tracks = numTracks; } // the toString for printing public String toString() { String description; description = title + "\t" + artist; return description; } }
Tri de tableaux Le triage est le processus d'ordonner une liste d'éléments Il y a plusieurs algorithmes pour trier une liste d'élements Ces algorithmes peuvent varier en performance Nous allons examiner deux algorithmes spécifiques: Tri par sélection Tri par insertion
Tri par sélection: En général L'approche pour le tri par sélection: Choisissez un item et placez-le dans sa position finale dans le tableau trié Répétez pour tous les autres items En plus de détailles: Trouvez le plus petit item dans la liste Échangez-le avec l'item dans la 1ere position Trouvez le prochain plus petit item dans la liste Échangez-le avec l'item dans la 2e position Répétez jusqu'à ce que tous les items soient dans la bonne ordre
Tri par sélection: La méthode Selection Sort Un exemple: original: 3 9 6 1 2 smallest is 1: 1 9 6 3 2 smallest is 2: 1 2 6 3 9 smallest is 3: 1 2 3 6 9 smallest is 6: 1 2 3 6 9 Voir SortGrades.java (page 342) Voir Sorts.java (page 343) -- la méthode selectionSort
Tri par sélection: La méthode selectionSort public static void selectionSort (int[] numbers) { int min, temp; for (int index = 0; index < numbers.length – 1; index++) min = index; for (int scan = index+1; scan < numbers.length; scan++) if (numbers[scan] < numbers[min]) min =scan; // Swap the values temp = numbers[min]; numbers[min] = numbers[index]; numbers[index] = temp; }
Tri par insertion: En général L'approche pour le tri par insertion: Choisissez un item et insérez-le dans la sous-liste triée dans la bonne ordre Répétez jusqu'à ce que tous les items soient insérés En plus de détailles: Considérez le 1er item comme étant la sous-liste triée (avec un item) Insérez le 2e item dans la sous-liste triée, en faisant décaler le 1er item si nécessaire pour pouvoir insérer le nouvel item Insérez le 3e item dans la sous-liste triée (de deux items), en faisant décaler les items comme nécessaire Répétez jusqu'à ce que tous les items soient insérés dans la bonne ordre
Tri de tableaux: Tri par insertion Un exemple: original: 3 9 6 1 2 insert 9: 3 9 6 1 2 insert 6: 3 6 9 1 2 insert 1: 1 3 6 9 2 insert 2: 1 2 3 6 9 Voir Sorts.java (page 343) -- la méthode insertionSort
Tri par insertion: La méthode insertionSort public static void insertionSort (int[] numbers) { for (int index = 1; index < numbers.length; index++) int key = numbers[index]; int position = index; while (position > 0 && numbers[position – 1] > key) numbers[position] = numbers[position – 1]; position --; } numbers[position] = key;
Comparaison de tri: Sélection et insertion Les tris par sélection and par insertion sont similaires en performance Ces deux tris ont une boucle extérieure qui fait l'analyse de tous les éléments et une boucle intérieure qui compare la valeur de la boucle extérieure avec presque toutes les valeurs de la liste Alors, il faut environ n2 comparaisons pour obtenir une liste triée de taille n Nous disons donc que ces tris sont d'ordre n2 Il y a autres tris qui sont plus efficaces: order n log2 n
Tri d'objets: Un exemple L'ordre d'une collection d'objets doit être défini par la personne qui définie la classe Rappelez-vous qu'une interface Java peut être utilisé pour guarantir qu'une classe particulière implémentera des méthodes particulières On peut utiliser l'interface Comparable et la méthode CompareTo pour développer un tri générique pour un ensemble d'objets Voir SortPhoneList.java et Contact.java (page 347-348)