flowchart TD A[Quelles opérations ?] --> B{Accès aléatoire fréquent ?} B -->|Oui| C[Tableau] B -->|Non| D{Insertions ou suppressions au début ou milieu ?} D -->|Oui| E[Liste Chaînée] D -->|Non| F{Principalement ajouts en fin ?} F -->|Oui| C F -->|Non| G[Les deux conviennent]
2 Fonctions pures ou impures : des effets de bord
AFFAIRE(
- définir la pureté - maths : théorie des probas
- exo 1 caractérisation théorique par duplication
- exo 2 exemple des nat pour comprendre le problème (logique vs efficacité)
- exo 3 - approche pragmatique - exemple du produit
)
2.1 Fonctions pures et impures
AFFAIRE(
- définir la pureté - maths : théorie des probas
- exo 1 caractérisation théorique par duplication
)
Exercice 2.1 (Une caractérisation de la pureté) Comment caractériser la pureté
2.2 Logique contre efficacité
AFFAIRE(
- exo 2 exemple des nat pour comprendre le problème (logique vs efficacité)
- somme alternative avec modification en place
- comparaison : logique vs efficacité )
2.3 Approche pragmatique : immutabilité aux interfaces, mutabilité confinée
AFFAIRE(
- exo 3 - approche pragmatique - exemple du produit
- algorithme sur des listes
- problèmes en API standard Java : le choix tardif de l’immutabilité - notamment pour les listes
- comparaison tableaux et listes chaînées pour les listes mutables de Java
)
Exercice 2.2 (Entiers naturels : Implémentation optimisée par une liste de chiffres) Les deux implémentations précédentes des entiers naturels, par induction (récurrence) et par restriction respectivement, présentent des défauts : la première est inefficace, représentant un entier naturel \(n\) par un chaînage de \(n + 1\) objets, la seconde impose une limite en taille aux entiers naturels, qui ne peuvent dépasser \(2^{31}\) puisque leur représentation en base deux comporte \(32\) chiffres au maximum, et qu’ils sont relatifs (signés comme on dit en informatique), ce qui fait un perdre un chiffre codant le signe. Pour résoudre ces deux problèmes, nous allons représenter un entier naturel en une certaine base (typiquement dix) par une liste de chiffres, précisément un tableau de chiffres, et implémenter les calculs qu’on apprend en école primaire et au collège avec les retenues.
- Calculer une approximation de \(2^{32}\) de tête. Quel est l’intervalle décrit par des entiers naturels de \(n\) chiffres en base \(b\) ?
- Définir une nouvelle classe
GrandNat
implémentantNat
.- Définir une constante statique (associée à la classe et non aux objets de la classe)
base
de typeNat
. L’initialiser à10
. - Définir un attribut de type
List<Integer>
représentant la liste de chiffres. On requiert que cette liste soit immutable pour garantir de bonnes propriétés logiques et de type tableau pour permettre un accès en temps constant à chaque chiffre. - Définir deux constructeurs, l’un ayant pour paramètre un tableau d’entiers de type
Integer...
, dit varargs, qui permet d’appeler le constructeur en notant les éléments du tableau comme une suite d’arguments, l’autre acceptant une liste d’entiers de typeInteger
. À chaque fois, vérifier l’entrée et créer une liste immutable de type tableau. Indication : demander à une IA comment créer uneArrayList
qui soit immutable à partir d’une liste donnée ou d’une suite finie de valeurs (de stylevarargs
).
- Définir une constante statique (associée à la classe et non aux objets de la classe)
- Ajouter à l’interface
Nat
les accesseurs qui vous paraissent utiles pour cette nouvelle classe d’implémentation. - Définir tous les accesseurs de la classe. La méthode
predecesseur
requiert de développer un algorithme de soustraction. - Définir la méthode
somme
en réalisant les sommes des chiffres à partir des unités, et en retenant1
si la somme dépasse la valeur de la base (moins une unité). On pourra prendre une liste chaînée de typeLinkedList<Integer>
comme structure intermédiaire pour stocker les résultats, pour éviter tout problème de redimensionnement, puis créer à partir d’elle la liste immutable de type tableau. - Définir la méthode
produit
en utilisant la multiplication russe, dans la base fixée, alors qu’elle est généralement utilisée en base deux. Il s’agit d’une formalisation algébrique de la multiplication qu’on pose. Indication : demander à une IA de décrire l’algorithme de la multiplication russe, en précisant si nécessaire que vous voulez généraliser la méthode à une base autre que deux.