Linf 1251 r cursion sur les listes
This presentation is the property of its rightful owner.
Sponsored Links
1 / 56

LINF 1251: Récursion sur les Listes PowerPoint PPT Presentation


  • 51 Views
  • Uploaded on
  • Presentation posted in: General

LINF 1251: Récursion sur les Listes. Peter Van Roy Département d’Ingénierie Informatique, UCL [email protected] Ce qu’on va voir aujourd’hui. Résumé du dernier cours Les listes Récursion sur les listes Pattern matching Développement descendant Complexité en temps.

Download Presentation

LINF 1251: Récursion sur les Listes

An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -

Presentation Transcript


Linf 1251 r cursion sur les listes

LINF 1251:Récursion sur les Listes

Peter Van Roy

Département d’Ingénierie Informatique, UCL

[email protected]

P. Van Roy, LINF1251


Ce qu on va voir aujourd hui

Ce qu’on va voir aujourd’hui

  • Résumé du dernier cours

  • Les listes

  • Récursion sur les listes

  • Pattern matching

  • Développement descendant

  • Complexité en temps

P. Van Roy, LINF1251


R sum du dernier cours

Résumédu dernier cours

P. Van Roy, LINF1251


Principes

Principes

  • Une fonction récursive est comme une boucle dans un langage impératif

    • Attention: si vous avez deux boucles imbriquées, vous avez besoin de deux fonctions récursives!

  • Si l’appel récursif est le dernier appel, alors la fonction récursive est exactement comme une boucle

    • Espace mémoire constante, temps proportionnel au nombre d’itérations

  • La programmation avec accumulateurs est recommandée

    • Pour assurer que l’appel récursif soit le dernier appel

    • On peut utiliser un invariant pour dériver un accumulateur

    • Comment trouver un bon invariant?

P. Van Roy, LINF1251


Comment trouver un bon invariant

Comment trouver un bon invariant?

  • Principe des “vases communicants”

    • Une formule en deux parties

    • Une partie “disparaît”; l’autre “accumule” le résultat

  • Exemple: calcul efficace des nombres de Fibonacci

    • Définition: F0=0, F1=1, Fn=Fn-1+Fn-2

    • Invariant: le triplet (n-i,Fi-1,Fi)

      • “Invariant” parce que les trois parties du triplet doivent toujours être dans cette relation

    • Un pas de l’exécution: (k,a,b) devient (k-1,b,a+b)

    • Valeur initiale: (n-1,0,1)

P. Van Roy, LINF1251


Calcul efficace des nombres de fibonacci

Calcul efficace des nombresde Fibonacci

  • Raisonnement sur l’invariant

    • Invariant: le triplet (n-i,Fi-1,Fi)

    • Un pas de l’exécution: (k,a,b) devient (k-1,b,a+b)

    • Valeur initiale: (n-1,0,1)

    • Valeur finale: (0,Fn-1,Fn)

  • Définition de la fonction:fun {Fibo K A B}if K==0 then Belse {Fibo K-1 B A+B} endend

  • Appel initial: {Fibo N-1 0 1}

P. Van Roy, LINF1251


Environnement contextuel d une proc dure 1

Environnement contextueld’une procédure (1)

  • Quand on définit une procédure, on fait deux choses

    • Déclaration de l’identificateur

    • Création de la procédure en mémoire: il y a deux parties, le code de la procédure et son environnement contextuel

  • Une procédure se souvient de l’endroit de sa naissance (son “environnement contextuel”)

  • Quel est l’environnement contextuel de cette procédure?declarefun {Iterate Si}if {IsDone Si} then Sielse {Iterate {Transform Si}} endend

P. Van Roy, LINF1251


Environnement contextuel d une proc dure 2

Environnement contextueld’une procédure (2)

  • Pour bien distinguer la déclaration de l’identificateur et la création de la procédure en mémoire, on peut écrire:declareIterate = fun {$ Si}if {IsDone Si} then Sielse {Iterate {Transform Si}} endend

  • La syntaxe fun {$ Si} … end représente une fonction en mémoire (sans identificateur: c’est une fonction anonyme)

    • Le “$” prend la place de l’identificateur

  • L’environnement contextuel contient donc{IsDone, Iterate, Transform}

P. Van Roy, LINF1251


Les listes

Les listes

P. Van Roy, LINF1251


Pourquoi les listes

Pourquoi les listes?

  • Dans le dernier cours, on a vu la récursion sur les entiers

    • Mais un entier est assez limité

    • On voudrait faire des calculs avec des structures plus complexes et avec beaucoup d’entiers en même temps!

  • La liste

    • Une collection ordonnée d’éléments (une séquence)

    • Une des premières structures utilisées dans les langages symboliques (Lisp, dans les années 50)

    • La plus utile des structures composées

P. Van Roy, LINF1251


D finition intuitive

Définition intuitive

  • Une liste est

    • la liste vide, ou

    • une paire (un cons) avec une tête et une queue

      • La tête est le premier élément

      • La queue est une liste (les éléments restants)

P. Van Roy, LINF1251


La syntaxe d une liste

La syntaxe d’une liste

  • Avec la notation EBNF:<List T> ::= nil | T ‘|’ <List T>

  • <List T> représente une liste d’éléments de type T et T représente un élément de type T

  • Attention à la différence entre | et ‘|’

P. Van Roy, LINF1251


Notation pour les types

Notation pour les types

  • <Int> représente un entier; plus précisément l’ensemble de tous les entiers

  • <List <Int>> représente l’ensemble de toutes les listes d’entiers

  • T représente l’ensemble de tous les éléments de type T; nous disons que T est une variable de type

    • Ne pas confondre avec une variable en mémoire!

P. Van Roy, LINF1251


Syntaxe pour les listes 1

Syntaxe pour les listes (1)

  • Liste vide: nil

  • Liste non-vide: H|T

    • L’opérateur infixe ‘|’

  • nil, 5|nil, 5|6|nil, 5|6|7|nil

  • nil, 5|nil, 5|(6|nil), 5|(6|(7|nil))

‘|’

5

‘|’

6

‘|’

7

nil

P. Van Roy, LINF1251


Syntaxe pour les listes 2

Syntaxe pour les listes (2)

  • Il existe un sucre syntaxique plus court

    • Sucre syntaxique = raccourci de notation qui n’a aucun effet sur l’exécution

  • nil, [5], [5 6], [5 6 7]

  • Attention: dans la mémoire de l’ordinateur, [5 6 7] et 5|6|7|nil sont identiques!

‘|’

5

‘|’

6

‘|’

7

nil

P. Van Roy, LINF1251


La syntaxe compl te une liste est un tuple

La syntaxe complète:une liste est un tuple

  • Une liste est un cas particulier d’un tuple

  • Syntaxe préfixe (l’opérateur ‘|’ devant)

    • nil‘|’(5 nil)‘|’(5 ‘|’(6 nil))‘|’(5 ‘|’(6 ‘|’(7 nil)))

  • Syntaxe complète

    • nil,‘|’(1:5 2:nil)‘|’(1:5 2:’|’(1:6 2:nil))‘|’(1:5 2:’|’(1:6 2:’|’(1:7 2:nil)))

P. Van Roy, LINF1251


La construction d une liste

La construction d’une liste

declare

X1=5|X2

X2=6|X3

X3=7|nil

‘|’

X1

5

‘|’

X2

6

‘|’

7

nil

X3

P. Van Roy, LINF1251


R sum des syntaxes possibles

Résumé des syntaxes possibles

  • On peut écrire

    X1=5|6|7|nil

    qui est un raccourci pour

    X1=5|(6|(7|nil))

    qui est un raccourci pour

    X1=‘|’(5 ‘|’(6 ‘|’(7 nil)))

  • La plus courte (attention au ‘nil’!)

    X1=[5 6 7]

P. Van Roy, LINF1251


Calculer avec les listes

Calculer avec les listes

  • Attention: une liste non vide est une paire!

  • Accès à la tête

    X.1

  • Accès à la queue

    X.2

  • Tester si la liste X est vide:

    if X==nil then … else … end

P. Van Roy, LINF1251


La t te et la queue

La tête et la queue

  • On peut définir des fonctions

    fun {Head Xs}

    Xs.1

    end

    fun {Tail Xs}

    Xs.2

    end

P. Van Roy, LINF1251


Exemple avec head et tail

Exemple avec Head et Tail

  • {Head [a b c]}

    donne a

  • {Tail [a b c]}

    donne [b c]

  • {Head {Tail {Tail [a b c]}}}

    donne c

  • Dessinez les arbres!

P. Van Roy, LINF1251


R cursion sur les listes

Récursion surles listes

P. Van Roy, LINF1251


Exemple de r cursion sur une liste

Exemple derécursion sur une liste

  • On a une liste d’entiers

  • On veut calculer la somme de ces entiers

    • Définir la fonction Sum

  • Définition inductive sur la structure de liste

    • Sum de la liste vide est 0

    • Sum d’une liste non vide L est

      {Head L} + {Sum {Tail L}}

  • P. Van Roy, LINF1251


    Somme des l ments d une liste m thode na ve

    Somme des éléments d’une liste (méthode naïve)

    fun {Sum L}

    if L==nil then

    0

    else

    {Head L} + {Sum {Tail L}}

    end

    end

    P. Van Roy, LINF1251


    Somme des l ments d une liste avec accumulateur

    Somme des éléments d’une liste (avec accumulateur)

    fun {Sum2 L A}

    if L==nil then

    A

    else

    {Sum2 {Tail L} A+{Head L}}

    end

    end

    P. Van Roy, LINF1251


    Transformer le programme pour obtenir l accumulateur

    Transformer le programme pour obtenir l’accumulateur

    • Arguments:

      • {Sum L}

      • {Sum2 L A}

    • Appels récursifs

      • {Head L} + {Sum {Tail L} }

      • {Sum2 {Tail L} A+{Head L} }

    • Cette transformation marche parce que l’addition est associative

      • Sum fait (1+(2+(3+4))), Sum2 fait ((((0+1)+2)+3)+4)

    P. Van Roy, LINF1251


    Autre exemple la fonction nth

    Autre exemple: la fonction Nth

    • Définir une fonction {Nth L N} qui renvoie la nième élément de L

    • Le type de Nth est:<fun {$ <List T> <Int>}:<T>>

    • Raisonnement:

      • Si N==1 alors le résultat est {Head L}

      • Si N>1 alors le résultat est {Nth {Tail L} N-1}

    P. Van Roy, LINF1251


    La fonction nth

    La fonction Nth

    • Voici la définition complète:fun {Nth L N}if N==1 then {Head L}elseif N>1 then {Nth {Tail L} N-1}endend

    • Qu’est-ce qui se passe si le nième élément n’existe pas?

    P. Van Roy, LINF1251


    Pattern matching

    Pattern matching

    P. Van Roy, LINF1251


    Sum avec pattern matching

    Sum avec pattern matching

    fun {Sum L}

    case L

    of nil then 0

    [] H|T then H+{Sum T}

    end

    end

    P. Van Roy, LINF1251


    Sum avec pattern matching1

    Sum avec pattern matching

    fun {Sum L}

    case L

    of nil then 0

    [] H|T then H+{Sum T}

    end

    end

    Une clause

    • “nil” est la forme (pattern) de la clause

    P. Van Roy, LINF1251


    Sum avec pattern matching2

    Sum avec pattern matching

    fun {Sum L}

    case L

    of nil then 0

    [] H|T then H+{Sum T}

    end

    end

    Une clause

    • “H|T” est la forme (pattern) de la clause

    P. Van Roy, LINF1251


    Pattern matching1

    Pattern matching

    • La première clause utilise of, les autres []

    • Les clauses sont essayées dans l’ordre

    • Une clause correspond si sa forme correspond

    • Une forme correspond, si l’étiquette (label) et les arguments correspondent

      • Les identificateurs dans la forme sont alors affectés aux parties correspondentes de la liste

  • La première clause qui correspond est exécutée, pas les autres

  • P. Van Roy, LINF1251


    Longueur d une liste

    Longueur d’une liste

    • Définition inductive

      • Longueur d’une liste vide est 0

      • Longueur d’une paire est 1 + longueur de la queue

        fun {Length Xs}

        case Xs

        of nil then 0

        [] X|Xr then 1+{Length Xr}

        end

        end

    P. Van Roy, LINF1251


    Longueur d une liste 2

    Longueur d’une liste (2)

    • Avec une forme en plus!

      fun {Length Xs}

      case Xs

      of nil then 0

      [] X1|X2|Xr then 2+{Length Xr}

      [] X|Xr then 1+{Length Xr}

      end

      end

    P. Van Roy, LINF1251


    Longueur d une liste 3

    Longueur d’une liste (3)

    • Quelle forme ne sera jamais choisie?

      fun {Length Xs}

      case Xs

      of nil then 0

      [] X|Xr then 1+{Length Xr}

      [] X1|X2|Xr then 2+{Length Xr}

      end

      end

    P. Van Roy, LINF1251


    Pattern matching en g n ral

    Pattern matching en général

    • Le pattern matching peut être utilisé pour beaucoup plus que les listes

    • Toute valeur, y compris nombres, atomes, listes, tuples, enregistrements

      • Nous allons voir les tuples dans le prochain cours

    • Les formes peuvent être imbriquées

    • Certains langages connaissent des formes encore plus générales (expressions régulières)

    P. Van Roy, LINF1251


    Calculs sur les listes

    Calculs sur les listes

    • Une liste est une liste vide ou une paire avec une tête et une queue

    • Un calcul avec une liste est un calcul récursif

    • Le pattern matching est une bonne manière d’exprimer de tels calculs

    P. Van Roy, LINF1251


    M thode g n rale pour la r cursion sur les listes

    Méthode générale pour la récursion sur les listes

    • Il faut traiter les listes de façon récursive

      • Cas de base:la liste est vide (nil)

      • Cas inductif:la liste est une paire (cons)

  • Une technique puissante et concise

    • Le pattern matching (correspondance des formes)

    • Fait la correspondance entre une liste et une forme (“pattern”) et lie les identificateurs dans la forme

  • P. Van Roy, LINF1251


    D veloppement descendant

    Développementdescendant

    P. Van Roy, LINF1251


    Le triangle de pascal 1

    Le triangle de Pascal (1)

    • Nous allons définir la fonction {Pascal N}

    • Cette fonction prend un entier N et donne la Nième rangée du triangle de Pascal, représentée comme une liste d’entiers

    • Une définition classique est que {Pascal N} est la liste des coefficients dans l’expansion de (a+b)n

    1

    1

    1

    1

    2

    1

    (0)

    1

    3

    3

    1

    (0)

    1

    4

    6

    4

    1

    P. Van Roy, LINF1251


    Le triangle de pascal 2

    Le triangle de Pascal (2)

    1

    • Calculez la fonction {Pascal N}

    • Pour la rangée 1, cela donne [1]

    • Pour la rangée N, déplacez à gauche la rangée N-1 et déplacez à droite la rangée N-1

    • Alignez les deux rangées déplacées et additionnez-les élément par élément pour obtenir la rangée N

    1

    1

    1

    2

    1

    (0)

    1

    3

    3

    1

    (0)

    1

    4

    6

    4

    1

    Déplacez à droite:

    [0 1 3 3 1]

    [1 3 3 1 0]

    Déplacez à gauche:

    P. Van Roy, LINF1251


    Sch ma de la fonction

    Schéma de la fonction

    Pascal N

    Pascal N-1

    Pascal N-1

    ShiftLeft

    ShiftRight

    AddList

    P. Van Roy, LINF1251


    Code de la fonction

    Code de la fonction

    declare

    fun{Pascal N}

    ifN==1then[1]

    else

    {AddList

    {ShiftLeft {Pascal N-1}}

    {ShiftRight {Pascal N-1}}}

    end

    end

    Pascal N

    Pascal N-1

    Pascal N-1

    ShiftLeft

    ShiftRight

    AddList

    P. Van Roy, LINF1251


    Fonctions auxiliaires 1

    Fonctions auxiliaires (1)

    fun {ShiftLeft L}

    case L of H|T then

    H|{ShiftLeft T}

    else [0]

    end

    end

    fun {ShiftRight L} 0|L end

    P. Van Roy, LINF1251


    Fonctions auxiliaires 2

    Fonctions auxiliaires (2)

    fun {AddList L1 L2}

    case L1 of H1|T1 then

    case L2 of H2|T2 then

    H1+H2|{AddList T1 T2}

    end

    else nil end

    end

    P. Van Roy, LINF1251


    Une d finition plus courte d addlist

    Une définition plus courte d’AddList

    • Un exemple d’une forme (pattern) plus compliquéefun {AddList L1 L2}case L1#L2 of (H1|T1)#(H2|T2) then(H1+H2)|{AddList T1 T2}else nil endend

    • L1#L2 est une paire de deux variables

      • Avec ‘#’ on peut grouper deux variables (un peu comme ‘|’)

    • La forme (H1|T1)#(H2|T2) fait la correspondance avec L1 et L2 en même temps

    P. Van Roy, LINF1251


    D veloppement descendant top down

    Développement descendant (”top-down”)

    • Ce que nous avons fait avec Pascal est un exemple de développement descendant (”top-down”)

    • D’abord, il faut comprendre comment résoudre le problème à la main

    • On résoud le problème en le décomposant en de tâches plus simples

    • La fonction principale (Pascal) est définie en utilisant des fonctions auxiliaires (ShiftLeft, ShiftRight et AddList)

    • On complète la solution en définissant les fonctions auxiliaires

    P. Van Roy, LINF1251


    Complexit en temps

    Complexité en temps

    P. Van Roy, LINF1251


    Temps d ex cution

    Temps d’exécution

    • Quel est le temps d’exécution de {Pascal N} en fonction de N?

      • Temps = tPascal(N)

    • Ce qui nous intéresse est la forme de la fonction tPascal(N)

      • Si nous achetons un ordinateur plus rapide, le temps diminuera: tPascal(N)/10 par exemple

      • Mais la forme de la fonction ne changera pas!

    • Qu’est-ce qui se passe quand N devient grand?

    P. Van Roy, LINF1251


    Complexit en temps1

    Complexité en temps

    • La complexité en temps O(f(n))

      • t(n) est de l’ordre f(n) s’il existe une constante c telle que t(n) ≤ c.f(n)

      • On écrit t(n) = O(f(n))

    • Par exemple, si tShiftLeft(n) est le temps d’exécution de {ShiftLeft L}, on peut dire:

      • tShiftLeft(n) = O(n) avec n=|L|

    • Pour {ShiftRight L} c’est plus simple:

      • tShiftRight(n) = O(1)

    P. Van Roy, LINF1251


    Complexit de pascal n

    Complexité de {Pascal N}

    • Quelle est la complexité de {Pascal N}?

      • tPascal(N) = O(2n)

      • Cela grandit très vite quand N augmente

        • Complexité exponentielle: n est dans l’exposant

        • L’histoire de l’inventeur des échecs et le shah

      • Même avec N relativement petit on ne peut pas calculer {Pascal N} dans un temps raisonnable

    • Pourquoi le temps augmente aussi vite?

      • Parce qu’il y a deuxappels récursifs {Pascal N-1}

    P. Van Roy, LINF1251


    Complexit exponentielle

    Complexité exponentielle

    declare

    fun{Pascal N}

    ifN==1then[1]

    else

    {AddList

    {ShiftLeft {Pascal N-1} }

    {ShiftRight {Pascal N-1} }}

    end

    end

    Pascal N

    Pascal N-1

    Pascal N-1

    ShiftLeft

    ShiftRight

    AddList

    P. Van Roy, LINF1251


    Fastpascal

    FastPascal

    • On peut faire un seulappel si on garde le résultat dans une variable locale Lfun {FastPascal N}if N==1 then [1]else L in L={FastPascal N-1} {AddList {ShiftLeft L} {ShiftRight L}}endend

    • La complexité devient O(n2)

      • Complexité polynomiale: un polynome en n

      • C’est beaucoup plus rapide que O(2n)!

    P. Van Roy, LINF1251


    R sum

    Résumé

    P. Van Roy, LINF1251


    R sum1

    Résumé

    • Les listes

      • Différentes syntaxes possibles, mais toujours la même représentation en mémoire

      • Récursion sur les listes

      • Pattern matching

    • Développement descendant (top-down)

      • Fonctions sur les listes

    • Complexité en temps

      • Complexité exponentielle et polynomiale

    P. Van Roy, LINF1251


  • Login