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 :

Échanger un noeud avec un de ses descendants


Sujet :

Caml

  1. #1
    Membre émérite
    Avatar de SpiceGuid
    Homme Profil pro
    Inscrit en
    Juin 2007
    Messages
    1 704
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2007
    Messages : 1 704
    Points : 2 990
    Points
    2 990
    Par défaut Échanger un noeud avec un de ses descendants
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    type tree =
       | Leaf
       | Node of tree * int * tree
    Je voudrais une fonction swap x y t qui, dans l'arbre t, échange le noeud x avec ses descendants de valeur y.

    Par exemple à partir de cet arbre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    let t = Node(Node(Node(Leaf,7,Leaf),1,Node(Leaf,4,Leaf)),
            5,
            Node(Node(Leaf,6,Leaf),3,Node(Leaf,2,Leaf)));;
     
    swap 5 6 t;;


    Voici ma fonction swap, mais je la trouve trop naïve car elle copie la totalité de l'arbre.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    let swap x y t =  
       let rec infix1 = function
          | Leaf -> Leaf
          | Node(l,a,r) ->
             if a = x then
                Node(infix2 l,y,infix2 r)
             else
                Node(infix1 l,a,infix1 r)
       and infix2 = function
          | Leaf -> Leaf
          | Node(l,a,r) ->
             Node(infix2 l,(if a = y then x else a),infix2 r)
       in infix1 t;;
    Dans mon cas d'utilisation le noeud x n'a toujours qu'un seul descendant de valeur y.
    Comment écrire swap x y t de façon a ce qu'elle ne copie qu'un chemin depuis la racine au lieu de la totalité de l'arbre ?
    Du même auteur: mon projet, le dernier article publié, le blog dvp et le jeu vidéo.
    Avant de poser une question je lis les règles du forum.

  2. #2
    LLB
    LLB est déconnecté
    Membre expérimenté
    Inscrit en
    Mars 2002
    Messages
    967
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 967
    Points : 1 410
    Points
    1 410
    Par défaut
    Tu peux renvoyer un booléen en plus qui indique s'il y a eu un changement dans l'arbre.

  3. #3
    LLB
    LLB est déconnecté
    Membre expérimenté
    Inscrit en
    Mars 2002
    Messages
    967
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 967
    Points : 1 410
    Points
    1 410
    Par défaut
    Plus simplement, tu peux utiliser l'égalité physique pour voir si l'un des deux fils a changé. Si non, tu renvoies l'ancien arbre.

  4. #4
    Membre éprouvé
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    832
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 832
    Points : 1 104
    Points
    1 104
    Par défaut
    La solution avec égalité physique est astucieuse mais, en un sens, "impure".
    J'ai préféré essayer une version explicite :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    let default def = function
      | None -> def
      | Some x -> x
     
     
    let change_node l l' a a' r r' = match l', a', r' with
    | None, None, None -> None
    | _ ->
        Some (Node (default l l', default a a', default r r'))
     
    let swap x y t =  
       let rec infix1 = function
          | Leaf -> None
          | Node(l,a,r) ->
              let infix, a' =
                if a = x then infix2, Some y
                else infix1, None in
              change_node l (infix l) a a' r (infix r)
       and infix2 = function
          | Leaf -> None
          | Node(l,a,r) ->
              let a' = if a = y then Some x else None in
              change_node l (infix2 l) a a' r (infix2 r)
       in
       (infix1 t);;
    En réalité il faudrait renvoyer (default t (infix1 t)), mais l'exposition de l'option permet de bien tester.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    # test;;
    - : tree =
    Node (Node (Leaf, 2, Leaf), 5,
     Node (Node (Leaf, 3, Leaf), 4, Node (Leaf, 6, Leaf)))
    # swap 5 6 test;;
    - : tree option =
    Some
     (Node (Node (Leaf, 2, Leaf), 6,
       Node (Node (Leaf, 3, Leaf), 4, Node (Leaf, 5, Leaf))))
    # swap 7 7 test;;
    - : tree option = None
    Mon deuxième test me fait penser qu'on pourrait tester "if x = y then None else ..", mais ce n'est pas bien important.

  5. #5
    Membre émérite
    Avatar de SpiceGuid
    Homme Profil pro
    Inscrit en
    Juin 2007
    Messages
    1 704
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2007
    Messages : 1 704
    Points : 2 990
    Points
    2 990
    Par défaut Merci, résolu
    Merci à vous deux.
    Il ne me reste plus qu'à choisir une solution et à l'adapter à mon cas d'utilisation (ils s'agit d'éditer graphiquement une lambda-expression par tirer-lâcher sur l'arbre de syntaxe abstraite).

    Du même auteur: mon projet, le dernier article publié, le blog dvp et le jeu vidéo.
    Avant de poser une question je lis les règles du forum.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 3
    Dernier message: 19/04/2016, 18h36
  2. Enregistrement d'un noeud avec ses descendants dans un graphe .
    Par malekmalek27021 dans le forum Général Java
    Réponses: 2
    Dernier message: 30/04/2014, 16h52
  3. Réponses: 11
    Dernier message: 29/09/2008, 10h57
  4. [treeview]insérer un noeud avec ses enfants
    Par new_wave dans le forum VB.NET
    Réponses: 4
    Dernier message: 14/05/2007, 16h55
  5. [XSLT]Trouver un noeud avec une condition sur ses sous-noeuds
    Par enguerran dans le forum XSL/XSLT/XPATH
    Réponses: 1
    Dernier message: 23/02/2007, 11h00

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