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

JavaScript Discussion :

Compréhension fonction récursive


Sujet :

JavaScript

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé Avatar de arwin
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    59
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 59
    Par défaut Compréhension fonction récursive
    Bonjour,
    voici une fonction récursive qui rempli un tableau avec des chiffres allant de 1 à n.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
     
    function countup(n) {
      if (n < 1) {
        return [];
      } else {
        const countArray = countup(n - 1); 
        countArray.push(n);
        return countArray;
      }
    }
    console.log(countup(5));
    Je bloque dans la compréhension du fonctionnement de cette fonction. La ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    const countArray = countup(n - 1);
    est censée appeler la fonction elle même avec comme paramètre n-1 donc on va au début de la fonction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    function countup(n-1) {
      if (n-1 < 1) {
        return [];
      } else
    et on va tomber encore une fois sur la ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    const countArray = countup(n - 2);
    qui nous fait remonter encore au début de la fonction et ainsi de suite jusqu'à n = 0 pour lequel la fonction retourne un tableau vide (et ne dépasse pas le else).

    Du coup on ne pourra jamais atteindre la ligne d'après, à savoir et donc on ne pourra rien "pusher" dans le tableau .... Parce que, et si mes connaissances sont correctes, lorsqu'on appelle une fonction on ne va plus exécuter le code qui se trouve après jusqu'à l'exécution complète de la fonction ....

    J'ai l'impression d'avoir raté quelque chose de fondamental ? c'est grave docteur ?

  2. #2
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    17 210
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 210
    Par défaut
    Bonjour,
    pour t'aider à comprendre ce qui ce passe, pas toujours évident d'ailleurs, il faut que tu observes le cheminement et rien de tel que de mettre des console.log().

    Essaie avec ce code et tu vas te rendre compte que tu as occulté quelque chose quand tu écris « Du coup on ne pourra jamais atteindre la ligne d'après, à savoir  ».
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    function countup(n) {
      if (n < 1) {
        console.log("end")
        return [];                           // création de l'array à remplir
      } else {
        console.log("else :", n)
        const countArray = countup(n - 1);   // ici on appelles la fonction avant d'exécuter ce qui suit 
        countArray.push(n);
        console.log(JSON.stringify(countArray));
        return countArray;
      }
    }
    console.log("Result : ", countup(5));

  3. #3
    Membre confirmé Avatar de arwin
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    59
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 59
    Par défaut
    Merci NoSmoking.. ton idée est génial mais je n'arrive toujours pas à saisir le truc.
    Après la ligne "end" le programme va retourner un tableau vide ... jusqu'à là c'est clair. Mais après il devrait sauter le else puisqu'on est dans le cas n=0 et donc on devrait sortir de la fonction et arriver à la ligne : console.log("Result : ", countup(5)); non ?
    Je ne comprend pas comment on a obtenu la ligne : [1] et ce qui suit
    Images attachées Images attachées  

  4. #4
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    17 210
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 210
    Par défaut
    Mais après il devrait sauter le else puisqu'on est dans le cas n=0 et donc on devrait sortir de la fonction
    tu oublies que la fonction s'auto appelle donc il y a un empilement puis un dépilement des appels.

    Essaies de comprendre en regardant ce pseudo code, ne cherche pas à l'exécuter, il plantera, c'est juste pour visualiser les empilements dépilements
    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
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    function countup(n)
      { // ce bloc est exécuté
        // ici n = 5
        if (n < 1) { // non exécutée
          console.log("end")
          return [];
        }
        else {
          const countArray = countup(n - 1)
          { // ce bloc est exécuté
            // ici n = 4
            if (n < 1) { // non exécutée
              return [];
            }
            else {
              const countArray = countup(n - 1)
              { // ce bloc est exécuté
                // ici n = 3
                if (n < 1) { // non exécutée
                  return [];
                }
                else {
                  const countArray = countup(n - 1)
                  { // ce bloc est exécuté
                    // ici n = 2
                    if (n < 1) { // non exécutée
                      return [];
                    }
                    else {
                      const countArray = countup(n - 1)
                      { // ce bloc est exécuté
                        // ici n = 1
                        if (n < 1) { // non exécutée
                          return [];
                        }
                        else {
                          const countArray = countup(n - 1)
                          { // ce bloc est exécuté
                            // ici n = 0, on arrête tout
                            if (n < 1) {
                              return [];
                            }
                            else { // non exécutée
                              const countArray = countup(n - 1);
                              countArray.push(n);
                              return countArray;
                            }
                          };
                          // maintenant countArray = []
                          // l'exécution se poursuit avec n = 1
                          countArray.push(n);
                          // countArray = [1]
                          return countArray;
                        }
                      };
                      // l'exécution se poursuit avec n = 2
                      countArray.push(n);
                      // countArray = [1, 2]
                      return countArray;
                    }
                  };
                  // l'exécution se poursuit avec n = 3
                  countArray.push(n);
                  // countArray = [1, 2, 3]
                  return countArray;
                }
              }
              // l'exécution se poursuit avec n = 4
              countArray.push(n);
              // countArray = [1, 2, 3, 4]
              return countArray;
            }
          };
          // l'exécution se poursuit avec n = 5
          countArray.push(n);
          // countArray = [1, 2, 3, 4, 5]
          return countArray;
        }
      }
    // l'exécution est terminée
    console.log("Result : ", countup(5));

  5. #5
    Membre confirmé Avatar de arwin
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    59
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 59
    Par défaut
    c'est bien de décortiquer le code, ca permet de voir où ça coince précisément et là du coup c'est à la ligne 50 : // l'exécution se poursuit avec n = 1 !!!!
    comment et pourquoi ? on était à n = 0 non ?! ( ligne 39 // ici n = 0, on arrête tout). Est-ce que le cas n = 1 (2, 3 etc ..) a été gardé en mémoire quelque part ?

    Parce que la limite qui reste floue dans ma tête c'est lorsqu'on arrive à n = 1,
    on a alors : const countArray = countup(0);
    On remonte alors au début de la fonction avant même de stocker quoi que ce soit dans countArray .... donc vraiment je ne vois pas comment ça se produit ce dépilement dont tu parle NoSmoking !!!!

  6. #6
    Expert confirmé
    Avatar de mathieu
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    10 672
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 10 672
    Par défaut
    à la ligne 37 du code NoSmoking, il y a l'appel de "countup(n - 1)" avec n = 1.
    donc à la ligne 50, on est dans même contexte donc il s'agit d'une variable n qui contient encore 1.

    chaque appel de la fonction countup va créer une nouvelle variable n qui gardera sa valeur uniquement pendant l'exécution de cette fonction. et donc la valeur de cette variable est indépendante des autres variables n des autres appels même si c'est la même fonction.

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

Discussions similaires

  1. Réponses: 1
    Dernier message: 19/04/2019, 11h10
  2. [VB6] XML, fonction récursive de recherche
    Par kboo dans le forum VB 6 et antérieur
    Réponses: 3
    Dernier message: 24/04/2006, 21h27
  3. [XSLT] fonction récursive à N niveaux
    Par Mike35 dans le forum XSL/XSLT/XPATH
    Réponses: 2
    Dernier message: 10/03/2006, 12h30
  4. Fonction récursive renvoi sur page d'erreur
    Par peck dans le forum Langage
    Réponses: 1
    Dernier message: 23/12/2005, 10h08
  5. Problème de fonction récursive avec un TcxDBTreeList
    Par isachat666 dans le forum Composants VCL
    Réponses: 1
    Dernier message: 05/12/2005, 13h12

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