Vous êtes sur la page 1sur 5

Constructions classiques en CAML

Spécial DS / TP et autres joyeusetés !

Parcours de liste (impératif) :

let reste = ref maliste in

while reste <> [] do (* Invariant de boucle : reste contient les elements restant à parcourir *)

let element = List.hd (!reste) in

[ACTION] reste := List.tl (!reste) done;

Parcours de liste (récursif) : let rec aux (liste) = (* Profil : list ->
Parcours de liste (récursif) :
let rec aux (liste) =
(* Profil : list -> unit
Terminaison : Longueur de liste
decroit dans N *)
match liste with
|[]
-> ()
|elt:reste ->
begin
[ACTION]
aux (reste)
end
in
aux (liste);

Récursivité terminale :

(* Equivalent imperatif :

x = depart while cond(x) do [ACTION] x := reste(x) done; *)

let rec aux (x) = if cond (x) then begin [ACTION] aux (reste(x)) end else

;

in

x

aux (depart);

Fonctions :

let fonction (param_1, (* Profil :

,

param_n) =

Parametres : - param_1 :

- param_n :

Precondition :

Description :

Resultat :

Effet de bord :

*)

[RESULTAT]

;;

Parcours tableau :

let lg = Array.length (tableau) in

for i = 0 to lg – 1 do (* Invariant de boucle : tous les éléments avant i ont été traités *)

let elt = tableau.(i) in

 

[ACTION]

done;

Découpages :

let (a, b) = couple in

List.hd (liste)

List.tl (liste)

Matching :

match valeur with |motif

-> resultat

|motif when condition -> resultat

|_

(* Le reste

*) -> resultat

Légende :

Commentaires Mots clefs CAML Noms de variables déjà déclarées Code important : l'oublier fera un plantage méchant !!!!

Inversion de liste (impératif) :

let reste

= ref depart

in

let arrivee = ref []

in

while reste <> [] do (* Invariant de boucle :

- reste contient le reste de la liste à inverser

- arrivee contient la partie deja inversee *)

let element = List.hd (!reste) in arrivee := element :: !arrivee;

reste := List.tl (!reste) done;

Inversion de liste (récursif terminal) :

let rec aux (inv, liste) = (* Profil : list * list -> list Terminaison : Longueur de liste decroit dans N Fonction auxiliaire qui inverse une liste *)

match liste with |[] -> inv |elt:reste -> aux (elt::inv, reste)

in

aux ([], depart); (* Resultat ici ! *)

Filtrage de liste (impératif : construction push / reverse) :

let reste

let arrivee = ref []

= ref depart in

in

while reste <> [] do (* Invariant de boucle :

- reste contient le reste de la liste à filtrer

- arrivee contient la partie filtree en sens inverse *)

let elt = List.hd (!reste) in

if cond (elt) then arrivee := elt :: !arrivee

;

reste := List.tl (!reste) done;

arrivee := List.rev (!arrivee); (* Resultat apres cette ligne *)

Filtrage de liste (récursif) :

 

let rec filtrer (liste, cond) = (* Profil : 'a list * ('a -> bool) → 'a list Terminaison : Longueur de liste decroit dans N Description : retourne la liste des elements de liste verifiant cond *)

match list with |[] -> [] |elt::reste when cond(elt) -> elt::filtrer (reste, cond) |_::reste -> filtrer (reste, cond)

 

;;

map (récursif) :

let rec map (fct, liste) = (* Profil : ('a -> 'b) * 'a list -> 'b list Terminaison : Longueur de liste decroit dans N Applique fct a tous les elements de liste *)

match liste with

 

|[]

-> []

|hd::tl -> fct(hd) :: map(fct, tl)

 

;;

Suite de fibonacci (impératif) :

 

let u_1 = ref 1 in let u_0 = ref 1 in

for i = 1 to n do (* Invariant de boucle :

- u_0 contient le terme i de la suite

- u_1 contient le terme i – 1 *)

let somme = !u_1 + !u_0 in u_1 := !u_0 u_0 := somme done;

(* Ici u_0 contient le n ieme terme *)

Liste des nombres de 1 à 10 (push / reverse) :

let liste = ref [] in

for i = 1 to 10 do (* Invariant de boucle : tous les entiers avant I ont ete ajoutes a liste *)

liste := I :: liste done;

liste := List.rev (liste); (* Resultat apres cette ligne *)

Tri par insertion (récursif) – compléxité O(n^2) :

let rec tri_insertion (liste) = (* Profil : 'a list -> 'a list Terminaison : Longueur de liste decroit dans N Retourne liste triee par ordre croissant *)

let rec inserer (sliste, elt) = (* Profil : 'a list * 'a -> 'a list Terminaison : Longueur de sliste decroit dans N Insere elt dans sliste en conservant l'ordre Retourne la liste obtenue *)

match sliste with |[] -> [elt] |hd::tl when hd < elt -> hd::inserer(tl, elt) |hd::tl -> elt::hd::tl

;;

in

match liste with

|[]

|hd::tl -> inserer (tri_insertion(tl), hd)

-> []

Tri rapide (récursif) - complexité O(n log n) :

let rec tri_rapide (liste) = (* Profil : 'a list -> 'a list Terminaison : Longueur de liste decroit dans N Retourne liste triee par ordre croissant *)

let rec partition (inf, egal, sup, liste, pivot) = (* Profil : 'a list * 'a list * 'a list * 'a list * 'a -> 'a list * 'a list * 'a list Retourne liste partitionnes en trois :

les elements inferieurs a pivot, ceux egaux, ceux superieurs *)

in

match liste with

|[]

|hd::tl ->

-> (inf, egal, sup)

if

partition (hd::inf, egal, sup, tl, pivot) else if hd = pivot then partition (inf, hd::egal, sup, tl, pivot) else partition (inf, egal, hd::sup, tl, pivot)

hd < pivot then

match liste with |[]

-> []

|pivot::reste -> let (inf, egal, sup) = partition ([], [], [], pivot::reste, pivot) in tri_rapide(inf) @ egal @ tri_rapide(sup)

;;

Ensemble des parties d'une liste (récursif) - complexité O(2^n) :

let rec parties (liste) = (* Profil : 'a list -> 'a list list Terminaison : Longueur de liste decroit dans N Retourne l'ensemble des parties de liste *)

in

match liste with

|[]

|hd::tl -> let parties_sans_hd = (parties tl) in let parties_avec_hd = List.map (fun l -> hd::l) parties_sans_hd

-> [[]]

List.append parties_avec_hd parties_sans_hd

;;