IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Caml Discussion :

probleme de recursivité


Sujet :

Caml

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2013
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2013
    Messages : 9
    Points : 9
    Points
    9
    Par défaut probleme de recursivité
    bonjour
    j'ai fais une fonction récursif en ocaml qui inverse une liste mais il a une erreur et je ne comprend pas la cause:voisi le code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    let rec rev l=match l with
      [] -> failwith "la liste est vide!"
      |h::[] ->h
      |h::t ->rev t @ h;;
    voisi le résultat:
    'a list list -> 'a list = <fun>

    @ pour concaténer 2 listes


    la question:pourquoi le parametre l est pour lui de type 'a list list,il doit etre de type 'a list.
    et comment je peut corriger cette erreur.

  2. #2
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Février 2012
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Février 2012
    Messages : 11
    Points : 16
    Points
    16
    Par défaut
    On va faire point par point. La première chose, c'est que dans ce genre de situation, on préfère utiliser le mot-clé function que utilisé la construction match ... with sur le dernier argument de la fonction.

    Grosso-modo, on peut considérer que ces deux codes sont équivalent:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    let f a = match a with
    | ...
    | ...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    let f = function
    | ...
    | ...
    Ensuite, il faut reprendre la logique du code pour comprendre ce qui va pas. Le déstructeur h :: t sépare une list en deux élément. Sa tête h et sa queue t. Pour une liste [0; 1; 2], h voudra 0 tandis que t voudra [1; 2]. Maintenant, l'opérateur @, lui, concatène 2 listes (il est du type 'a list -> 'a list -> 'a list). Ainsi, grâce au système d'inférence des types, tu exiges à ce que la tête h soit du type 'a list puisque tu l'utilise avec @. Si nous voulons une fonction dont la signature est 'a list -> 'a list, nous devrions avoir ceci plutôt:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    let rec rev = function
    | [] -> [] (* le rev d'une liste vide est une liste vide, pas besoin de lever une exception *)
    | h :: t -> rev t @ [h]
    Cependant, ce code, même si il fonctionne, il est lent. En effet, la complexité de l'opérateur de concaténation est de O(n), ainsi, la complexité de ton rev et de O(n²). Ce que je conseille en général aux personnes cherchant à faire cette fonction, c'est de refaire la fonction rev_append. Elle permet d'avoir spontanément une complexité O(n) et la fonction rev n'est qu'un cas particulier de rev_append.

    Ou sinon, tu peux te renseigner sur les transformations que l'on peut faire sur les fonctions récursives pour quelles deviennent tail récursif ! Voilà, bonne chance.

  3. #3
    Membre émérite
    Avatar de prgasp77
    Homme Profil pro
    Ingénieur en systèmes embarqués
    Inscrit en
    Juin 2004
    Messages
    1 306
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur en systèmes embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 306
    Points : 2 466
    Points
    2 466
    Par défaut
    Bonjour lucci57. Les conseils de Dinoosaure sont particulièrement bons, je te suggère de les suivre. Pour t'en persuader voici une « trace » de ce que tu cherches à faire face à ce qui serait « logique » de faire.
    rev [0;1;2;3]
    = (rev [1;2;3]) @ [0]
    = (rev [2;3] @ [1]) @ [0]
    = ((rev [3] @ [2]) @ [1]) @ [0]
    = (([3] @ [2]) @ [1]) @ [0]
    = ([3; 2] @ [1]) @ [0]
    = ({3 :: ([2] @ [1])) @ [0]
    = (3 :: [2; 1]) @ [0]
    = [3;2;1] @ [0]
    = 3 :: ([2;1] @ [0])
    = 3 :: (2 :: ([1] @ [0]))
    = 3 :: (2 :: [1;0])
    = 3 :: [2;1;0]
    = [3;2;1;0]
    rev_append [0;1;2;3] []
    = rev_append [1;2;3] [0]
    = rev_append [2;3] [1;0]
    = rev_append [3] [2;1;0]
    = rev_append [] [3;2;1;0]
    = [3;2;1;0]
    Il ne te restes plus qu'à coder cette fonction que l'on appelle rev_append. rev_append l1 l2 concatène l1 inversée à la fin de l2. rev_append l1 l2 produit le même résultat que l2 @ (rev l1) mais en bien plus efficace. Comme l'a dit Dinoosaure, on défini généralement rev l1 comme rev_append l1 [].

    Cdlt,
    -- Yankel Scialom

Discussions similaires

  1. Probleme de recursivite
    Par grogan dans le forum Langage
    Réponses: 1
    Dernier message: 14/08/2006, 20h27
  2. Probleme de recursivité
    Par lila13 dans le forum Langage
    Réponses: 6
    Dernier message: 05/05/2006, 11h33
  3. [Tableaux] petit probleme de recursiviter
    Par jeff_! dans le forum Langage
    Réponses: 13
    Dernier message: 01/02/2006, 16h50
  4. Probleme de recursivite (lie au TSP) :(
    Par piff62 dans le forum Algorithmes et structures de données
    Réponses: 7
    Dernier message: 05/02/2005, 11h30
  5. [FLASH MX 2004]-probleme de recursivité.
    Par calfater dans le forum Flash
    Réponses: 3
    Dernier message: 10/05/2004, 19h48

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo