Les listes Caml Option informatique 2016-2017 Structures de données • En informatique, une structure de données abstraite est la description d’une structure logique destinée à organiser et à agir sur des données indépendamment de la mise en œuvre effective de ces structures. Structures de données • En informatique, une structure de données abstraite est la description d’une structure logique destinée à organiser et à agir sur des données indépendamment de la mise en œuvre effective de ces structures. • Aujourd’hui les listes, plus tard pile, file et arbre. Listes Caml : caractéristiques générales • Les listes Caml sont homogènes, i.e. contiennent tous des éléments du même type (int list, bool list, int list list ...) Listes Caml : caractéristiques générales • Les listes Caml sont homogènes, i.e. contiennent tous des éléments du même type (int list, bool list, int list list ...) • Différence notable avec python. Listes Caml : caractéristiques générales • Les listes Caml sont homogènes, i.e. contiennent tous des éléments du même type (int list, bool list, int list list ...) • Différence notable avec python. • Elles peuvent grossir dynamiquement par ajout d’un élément uniquement en tête de liste Listes Caml : caractéristiques générales • Les listes Caml sont homogènes, i.e. contiennent tous des éléments du même type (int list, bool list, int list list ...) • Différence notable avec python. • Elles peuvent grossir dynamiquement par ajout d’un élément uniquement en tête de liste • On dispose de fonctions pour accéder à l’élément de tête, Listes Caml : caractéristiques générales • Les listes Caml sont homogènes, i.e. contiennent tous des éléments du même type (int list, bool list, int list list ...) • Différence notable avec python. • Elles peuvent grossir dynamiquement par ajout d’un élément uniquement en tête de liste • On dispose de fonctions pour accéder à l’élément de tête, • et pour accéder à la liste à laquelle on aurait ôté la tête. Listes Caml : caractéristiques générales • Les listes Caml sont homogènes, i.e. contiennent tous des éléments du même type (int list, bool list, int list list ...) • Différence notable avec python. • Elles peuvent grossir dynamiquement par ajout d’un élément uniquement en tête de liste • On dispose de fonctions pour accéder à l’élément de tête, • et pour accéder à la liste à laquelle on aurait ôté la tête. • Ceci va fortement influencer notre façon de programmer des fonctions utilisant des listes : récursivité et filtrage. Constructions des listes Caml • Construction explicite : les éléments sont séparés par des points-virgules, le tout entre crochets : [1; 3; 5] Constructions des listes Caml • Construction explicite : les éléments sont séparés par des points-virgules, le tout entre crochets : [1; 3; 5] • La liste vide est [] . Elle est polymorphe ’a list Constructions des listes Caml • Construction explicite : les éléments sont séparés par des points-virgules, le tout entre crochets : [1; 3; 5] • La liste vide est [] . Elle est polymorphe ’a list • Ajout d’un élément en tête de liste grâce à l’opérateur infixe « conse » :: Constructions des listes Caml • Construction explicite : les éléments sont séparés par des points-virgules, le tout entre crochets : [1; 3; 5] • La liste vide est [] . Elle est polymorphe ’a list • Ajout d’un élément en tête de liste grâce à l’opérateur infixe « conse » :: • selon e :: liste : calcule une nouvelle liste égale à la précédente à laquelle l’élément e a été ajouté en tête. Constructions des listes Caml • Construction explicite : les éléments sont séparés par des points-virgules, le tout entre crochets : [1; 3; 5] • La liste vide est [] . Elle est polymorphe ’a list • Ajout d’un élément en tête de liste grâce à l’opérateur infixe « conse » :: • selon e :: liste : calcule une nouvelle liste égale à la précédente à laquelle l’élément e a été ajouté en tête. • ainsi 1 : : (3 : : (5 : : [])) permet d’obtenir la liste [1; 3; 5] . Constructions des listes Caml • Construction explicite : les éléments sont séparés par des points-virgules, le tout entre crochets : [1; 3; 5] • La liste vide est [] . Elle est polymorphe ’a list • Ajout d’un élément en tête de liste grâce à l’opérateur infixe « conse » :: • selon e :: liste : calcule une nouvelle liste égale à la précédente à laquelle l’élément e a été ajouté en tête. • ainsi 1 : : (3 : : (5 : : [])) permet d’obtenir la liste [1; 3; 5] . • Le constructeur conse, : : est associatif à droite : Constructions des listes Caml • Construction explicite : les éléments sont séparés par des points-virgules, le tout entre crochets : [1; 3; 5] • La liste vide est [] . Elle est polymorphe ’a list • Ajout d’un élément en tête de liste grâce à l’opérateur infixe « conse » :: • selon e :: liste : calcule une nouvelle liste égale à la précédente à laquelle l’élément e a été ajouté en tête. • ainsi 1 : : (3 : : (5 : : [])) permet d’obtenir la liste [1; 3; 5] . • Le constructeur conse, : : est associatif à droite : • Par exemple 1 : : 3 : : 5 : : [] est équivalent à l’expression précédente et donne aussi [1; 3; 5] Constructions des listes Caml • Accès à l’élément de tête : hd (pour head) Constructions des listes Caml • Accès à l’élément de tête : hd (pour head) • Accès à la liste à laquelle on aurait ôté la tête : tl (pour tail = queue) Constructions des listes Caml • Accès à l’élément de tête : hd (pour head) • Accès à la liste à laquelle on aurait ôté la tête : tl (pour tail = queue) • Concaténation de deux listes à l’aide de l’opérateur infixe @ : [1; 2; 3] @ [4; 5] rend [1; 2; 3; 4; 5] Constructions des listes Caml • Accès à l’élément de tête : hd (pour head) • Accès à la liste à laquelle on aurait ôté la tête : tl (pour tail = queue) • Concaténation de deux listes à l’aide de l’opérateur infixe @ : [1; 2; 3] @ [4; 5] rend [1; 2; 3; 4; 5] • Attention :: n’agit pas comme append en python qui modifie la liste initiale. Constructions des listes Caml • Accès à l’élément de tête : hd (pour head) • Accès à la liste à laquelle on aurait ôté la tête : tl (pour tail = queue) • Concaténation de deux listes à l’aide de l’opérateur infixe @ : [1; 2; 3] @ [4; 5] rend [1; 2; 3; 4; 5] • Attention :: n’agit pas comme append en python qui modifie la liste initiale. • De même hd , tl et @ ne modifient pas la ou les listes. On récupère de nouvelles listes qui ont été calculées. Listes Caml : complexité • À connaître pour évaluer les complexités de nos propres fonctions. Listes Caml : complexité • À connaître pour évaluer les complexités de nos propres fonctions. • hd liste , tl liste , element :: liste sont en temps constant O(1) Listes Caml : complexité • À connaître pour évaluer les complexités de nos propres fonctions. • hd liste , tl liste , element :: liste sont en temps constant O(1) • liste1 @ liste2 est linéaire en la taille de liste1 Révisons nos gammes : implémentations des fonctions élémentaires • longueur : ’a list -> int donnant la longueur d’une liste ; Révisons nos gammes : implémentations des fonctions élémentaires • longueur : ’a list -> int donnant la longueur d’une liste ; • Rem : cette fonction existe en Caml : list_length ; Révisons nos gammes : implémentations des fonctions élémentaires • longueur : ’a list -> int donnant la longueur d’une liste ; • Rem : cette fonction existe en Caml : list_length ; • appartenance : ’a -> ’a list -> bool indiquant si un élément appartient à une liste ; Révisons nos gammes : implémentations des fonctions élémentaires • longueur : ’a list -> int donnant la longueur d’une liste ; • Rem : cette fonction existe en Caml : list_length ; • appartenance : ’a -> ’a list -> bool indiquant si un élément appartient à une liste ; • Rem : cette fonction existe en Caml : mem ; Révisons nos gammes : implémentations des fonctions élémentaires • longueur : ’a list -> int donnant la longueur d’une liste ; • Rem : cette fonction existe en Caml : list_length ; • appartenance : ’a -> ’a list -> bool indiquant si un élément appartient à une liste ; • Rem : cette fonction existe en Caml : mem ; • dernier : ’a list -> ’a qui rend le dernier élément d’une liste et lève une exception si nécessaire ; Révisons nos gammes : implémentations des fonctions élémentaires • longueur : ’a list -> int donnant la longueur d’une liste ; • Rem : cette fonction existe en Caml : list_length ; • appartenance : ’a -> ’a list -> bool indiquant si un élément appartient à une liste ; • Rem : cette fonction existe en Caml : mem ; • dernier : ’a list -> ’a qui rend le dernier élément d’une liste et lève une exception si nécessaire ; • max_liste : ’a list -> ’a qui rend le plus grand élément d’une liste d’entiers ou de flottants et lève une exception si nécessaire ; Révisons nos gammes : implémentations des fonctions élémentaires • longueur : ’a list -> int donnant la longueur d’une liste ; • Rem : cette fonction existe en Caml : list_length ; • appartenance : ’a -> ’a list -> bool indiquant si un élément appartient à une liste ; • Rem : cette fonction existe en Caml : mem ; • dernier : ’a list -> ’a qui rend le dernier élément d’une liste et lève une exception si nécessaire ; • max_liste : ’a list -> ’a qui rend le plus grand élément d’une liste d’entiers ou de flottants et lève une exception si nécessaire ; • concat ’a list -> ’a list -> ’a list qui concatène deux listes (mais sans utiliser @ bien évidemment...) ; Révisons nos gammes : implémentations des fonctions élémentaires • nieme : int -> ’a liste -> ’a qui rend le n-ième élément d’une liste s’il existe (compté à partir de 0) et lève une exception si nécessaire. Révisons nos gammes : implémentations des fonctions élémentaires • nieme : int -> ’a liste -> ’a qui rend le n-ième élément d’une liste s’il existe (compté à partir de 0) et lève une exception si nécessaire. • map_list : (’a -> ’b) -> ’a list -> ’b list qui rend la liste obtenue en appliquant la fonction f à chaque élément de la liste initiale. Révisons nos gammes : implémentations des fonctions élémentaires • nieme : int -> ’a liste -> ’a qui rend le n-ième élément d’une liste s’il existe (compté à partir de 0) et lève une exception si nécessaire. • map_list : (’a -> ’b) -> ’a list -> ’b list qui rend la liste obtenue en appliquant la fonction f à chaque élément de la liste initiale. • Rem : cette fonction existe en Caml : map Révisons nos gammes : implémentations des fonctions élémentaires • nieme : int -> ’a liste -> ’a qui rend le n-ième élément d’une liste s’il existe (compté à partir de 0) et lève une exception si nécessaire. • map_list : (’a -> ’b) -> ’a list -> ’b list qui rend la liste obtenue en appliquant la fonction f à chaque élément de la liste initiale. • Rem : cette fonction existe en Caml : map • fait_liste : (’a -> unit) -> ’a list -> unit qui applique la fonction (normalement à effet de bord) successivement à chaque élement de la liste initiale. Révisons nos gammes : implémentations des fonctions élémentaires • nieme : int -> ’a liste -> ’a qui rend le n-ième élément d’une liste s’il existe (compté à partir de 0) et lève une exception si nécessaire. • map_list : (’a -> ’b) -> ’a list -> ’b list qui rend la liste obtenue en appliquant la fonction f à chaque élément de la liste initiale. • Rem : cette fonction existe en Caml : map • fait_liste : (’a -> unit) -> ’a list -> unit qui applique la fonction (normalement à effet de bord) successivement à chaque élement de la liste initiale. • Rem : cette fonction existe en Caml : do_list Révisons nos gammes : implémentations des fonctions élémentaires • nieme : int -> ’a liste -> ’a qui rend le n-ième élément d’une liste s’il existe (compté à partir de 0) et lève une exception si nécessaire. • map_list : (’a -> ’b) -> ’a list -> ’b list qui rend la liste obtenue en appliquant la fonction f à chaque élément de la liste initiale. • Rem : cette fonction existe en Caml : map • fait_liste : (’a -> unit) -> ’a list -> unit qui applique la fonction (normalement à effet de bord) successivement à chaque élement de la liste initiale. • Rem : cette fonction existe en Caml : do_list • Passons au TD sur les listes...