INF121: Algorithmique et Programmation Fonctionnelle

publicité
INF121:
Algorithmique et Programmation Fonctionnelle
Cours 7 : Listes (suite et fin)
Année 2013 - 2014
Brefs rappels sur les listes
Une liste c’est :
I
une suite finie de valeurs de même type
I
contenant un nombre arbitraire d’éléments
I
fournis selon un ordre donné ([5, 8, 4] 6= [8, 5, 4])
Le type liste_de_t peut être défini par un type (union) récursif :
I
la constante Nil représente la liste vide
I
le constructeur Cons(e,l) représente l’ajout en tête de e à l
Cons (expr1, Cons (expr2, ...Cons (exprn, Nil) ...))
→ Un élément du type list_de_t est une valeur (comme une autre !)
→ On peut définir des listes d’entiers, booléens, réels, fonctions, etc.
1 / 10
Le type prédéfini pour les listes en Ocaml
OCaml fournit un constructeur de type list prédéfini
I
Nil est noté
I
Cons est exprimé par un opérateur infixé
[]
::
Exemple : Listes en notation OCaml
I
Cons (2, Nil) correspond à 2::[ ]
I
Cons (4,Cons (9, Nil)) correspond à 4::(9::[ ])
Quelques raccourcis de notation :
I
v1::(v2::...::(vn::[ ])) peut être noté v1::v2:: ...vn::[ ]
I
v1::v2::... vn::[ ] peut être noté [v1;v2;...;vn]
le type list_of_t devient t list
DEMO :
les listes en notation Ocaml
2 / 10
Retour sur le pattern-matching
Rien ne bouge . . .
⇒ Même règles, même expressivité, mais une nouvelle syntaxe
ensembles de valeurs attendues
liste vide
liste non vide
liste à un seul élément
liste non vide
dont le premier élément est 1
(dans le cas d’une liste d’entiers)
...
filtre
[]
_::_, _::l,
e::l, e::_
e::[], _::[],
[_], [e]
1::_
...
3 / 10
Retour sur les exercices du cours précédent
Avec ces nouvelles notations
Pour des listes d’entiers :
I
somme : renvoie la somme des éléments d’une liste
I
appartient : indique si un élément appartient à une liste
I
dernier : renvoie le dernier élément d’une liste
I
minimum : renvoie le minimum d’une liste d’entiers
I
pairs : renvoie les entiers pairs d’une liste
I
supprime : supprime une/toutes les occurrences d’un élément
I
concatene : concaténation de deux listes
I
partition : partitionne une “liste de paires” en une “paire de listes”
I
est_croissante : indique si une liste est croissante
DEMO :
Implémentation de certaines de ces fonctions
4 / 10
D’autres exemples de fonctions sur les listes
Une liste est-elle une sous-liste d’une autre ?
Exemples :
I
[ e2 ; e4 ; e5 ] est une sous-liste de [e1 ; e2 ; e3 ; e4 ; e5 ; e6]
I
[ e2 ; e4 ; e5 ; e7 ] n’est pas une sous-liste de [e2 ; e3 ; e4 ; e5 ; e6]
I
[ e4 ; e2 ; e5 ] n’est pas une sous-liste de [e1 ; e2 ; e3 ; e4 ; e5 ; e6]
Analyse :
I
ce predicat prend deux listes l1 et l2 en paramètre
I
l2 doit être obtenue en “supprimant” certains éléments de l1
Fermeture-Eclair
zip: prend en paramètre un couple de liste (de même taille) et renvoie la
liste des couples correspondants
Exemples :
I
zip [1; 3; 8] [2; 9; 8] est la liste [(1,2); (3,9); (8,8)]
I
zip [1; 3; 8] [2] n’est pas défini . . .
5 / 10
Quelques opérateurs prédéfinis sur le type list
let l1 = [3; 8; 7; 1]
Description
nième élément
longueur
tête
fin
inverse
concaténation
Opérateur
List.nth
List.length
List.hd
List.tl
List.rev
@
Exemple
List.nth l1 2 = 7
List.length l1 = 4
List.hd l1 = 4
List.tl l1 = [8;7;1]
List.rev l1 = [1;7;8;3]
l1 @ [2;3] = [3; 8; 7; 1; 2; 3]
Plus de détails sur
caml.inria.fr/pub/docs/manual-ocaml/libref/List.html
6 / 10
Tris de listes
Motivations
Trier ≈ ranger les éléments d’une liste selon un ordre donné
(ex., < pour int):
tri
liste quelconque −→ liste triée
Exemple
tri
[2;1;9;4] −→ [1;2;4;9]
I
type person = Toto | Titi | Tata
I
[Titi;Tata;Toto] −→ [Toto;Titi;Tata]
tri
Motivations ?
I
représentation canonique du (multi-ensemble) des elts d’une liste
I
certains traitements seront plus efficaces
I
une étape nécessaire dans de nombreux algorithmes plus généraux
⇒ ∃ nombreux algorithmes de tri, qui diffèrent par :
I
leur efficacité (en temps d’exécution, en mémoire)
I
leur difficulté à programmer, à prouver
7 / 10
Tris de listes
Quelques fonctions préliminaires
Recherche d’un élément dans une liste triée
→ on peut interrompre la recherche dès que l’on “dépasse” l’élément cherché
let rec appartient (e:int) (l:int list):bool=
(* l est croissante *)
match l with
| [] → false
| x::lp → e=x || (e > x) && (appartient e lp)
Insérer un élément dans une liste triée
(en produisant une nouvelle liste triée)
let rec inserer (e:int) (l:int list):int list=
(* l est croissante, le resultat est une liste
croissante *)
match l with
| [] → [e]
| x::lp → if e<x then e::l else x::(inserer e lp)
8 / 10
Deux exemples d’algorithmes de tri
Tri par insertion
“isoler un élément de l (la tête), trier (récursivement !) les autres éléments, et
insérer l’élément isolé à sa place dans la liste résultat”
Tri par sélection
“construire la liste résultat par ajouts successifs (en tête) des éléments de la
liste initiale l sélectionnés par ordre croissant”
Indication : deux fonction auxilliaires utiles
I
min_list: élément minimal d’une liste
I
supprime: supprime la 1ère occurence d’un élément dans une liste
9 / 10
Conclusion
Les listes : un type de données incontournable
I
Peuvent être définies explicitementt par un type union (récursif) :
I constructeurs Cons et Nil
I
I
I
I
En pratique : on utilise plutôt le type list de OCaml
::, [], [v1;v2;...;vn], @, . . .
fonctions récursives sur les listes :
I
I
I
“first-class citizens”
toutes les règles de typage s’appliquent, pattern-matching, etc.
identifier et définir le(s) cas de base
identifier et définir le(s) cas de récurrence
2 algorithmes de tri : tri par insertion et tri par sélection
Important
I
Vérifiez que vous savez écrire les fonctions vues dans ce cours
I
Jetez un coup d’oeil aux opérateurs prédéfinis du type List . . .
10 / 10
Téléchargement