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

Langage PHP Discussion :

Garder en mémoire une valeur pour une fonction à récursivité


Sujet :

Langage PHP

  1. #1
    Membre éclairé
    Inscrit en
    Septembre 2006
    Messages
    685
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 685
    Points : 658
    Points
    658
    Par défaut Garder en mémoire une valeur pour une fonction à récursivité
    Bonjour à tous,

    Désolé, pour ce problème de débutant, mais je ne sais pas comment garder en mémoire une valeur pour une fonction récursive.

    Je vais vous montrer un exemple tout bête :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    function soustrait($n)
    {
      if( $n > 5 )
      {
         $t = $n - 5;
         soustrait($t);
      }
       return $t;
    }
    echo soustrait(22);
    Avec cette fonction j'obtiens pour résultat 17, hors ce n'est pas ce que je désire obtenir, je souhaites que tant que le nombre est supérieur à 5, la fonction s'appelle, que donc au final, le résultat soit de 2.

    Comment fait-on pour obtenir ceci ?

    Merci !

  2. #2
    Membre expert

    Profil pro
    imposteur
    Inscrit en
    Avril 2003
    Messages
    3 308
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : imposteur

    Informations forums :
    Inscription : Avril 2003
    Messages : 3 308
    Points : 3 377
    Points
    3 377
    Par défaut
    remplace par

  3. #3
    Membre éclairé
    Inscrit en
    Septembre 2006
    Messages
    685
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 685
    Points : 658
    Points
    658
    Par défaut
    Ah yes
    J'aurais dû y penser

    Merci

  4. #4
    Membre expérimenté

    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 278
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 278
    Points : 1 639
    Points
    1 639
    Par défaut
    Tu n'es pas obligé d'utiliser une fonction récursive :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    function soustrait($n) {
      while ($n<=5) {
        $n=$n-5;
        }
      return $n;  
      }
    echo soustrait(22);

  5. #5
    Membre expert

    Profil pro
    imposteur
    Inscrit en
    Avril 2003
    Messages
    3 308
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : imposteur

    Informations forums :
    Inscription : Avril 2003
    Messages : 3 308
    Points : 3 377
    Points
    3 377
    Par défaut
    Citation Envoyé par vg33
    Tu n'es pas obligé d'utiliser une fonction récursive
    Il me semble que c'est valable dans tous les cas, et qu'à chaque algorithme itératif on peut faire correspondre un algorithme récursif (et inversement). A confirmer.

  6. #6
    Membre éclairé
    Inscrit en
    Septembre 2006
    Messages
    685
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 685
    Points : 658
    Points
    658
    Par défaut
    Ah j'ai une autre question sur ce même sujet.

    Cette fois ci, je souhaites garder dans un coin, le résultat d'une opération, qui sera effectué à chaque appel récursif.

    Par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    $array= array();
    function divise($n, $d)
    {
      $r = $n/$d;
      $array[] = $r;
      if( !is_float($r) )
        return divise($r, $d);
      return $array;
    }
    print_r(divise(20, 5));
    Donc ici, je voudrais que mon array() soit complété au fur et à mesure tant que $r n'est pas un nombre à virgule.

    C'est possible de faire ça ?
    Je suis obligé de le passer en paramètre de la fonction ?

    Oui vg33, mais cette fonction n'était qu'à titre d'exemple, je sais bien que la récursivité est inutile ici, d'ailleurs même la fonction ne sert à rien

  7. #7
    Membre expérimenté

    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 278
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 278
    Points : 1 639
    Points
    1 639
    Par défaut
    Citation Envoyé par Eusebius
    Il me semble que c'est valable dans tous les cas, et qu'à chaque algorithme itératif on peut faire correspondre un algorithme récursif (et inversement). A confirmer.
    De façon générale, ce doit être vrai.
    Mais, à ma connaissance, il vaut mieux éviter une fonction récursive, pour des raisons de performances et vu le risque de boucles infinies et de résultats aberrants.
    Tu confirmes ?

  8. #8
    Membre expérimenté

    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 278
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 278
    Points : 1 639
    Points
    1 639
    Par défaut
    Citation Envoyé par Xunil
    Donc ici, je voudrais que mon array() soit complété au fur et à mesure tant que $r n'est pas un nombre à virgule.
    Tu dois déclarer ton array comme variable globale.

  9. #9
    Membre expert

    Profil pro
    imposteur
    Inscrit en
    Avril 2003
    Messages
    3 308
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : imposteur

    Informations forums :
    Inscription : Avril 2003
    Messages : 3 308
    Points : 3 377
    Points
    3 377
    Par défaut
    Si j'ai bien compris ce que tu veux faire...

    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
    $array= array();
    function divise($n, $d)
    {
      $r = $n/$d;
      if( !is_float($r) ) {
        $arr = divise($r, $d);
        array_push($arr, $r);
        return $arr;
      }
      else {
        $arr[] = $r;
        return $arr;
      }
    }
    print_r(divise(20, 5));
    Code non testé.

  10. #10
    Membre expert

    Profil pro
    imposteur
    Inscrit en
    Avril 2003
    Messages
    3 308
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : imposteur

    Informations forums :
    Inscription : Avril 2003
    Messages : 3 308
    Points : 3 377
    Points
    3 377
    Par défaut
    Citation Envoyé par vg33
    De façon générale, ce doit être vrai.
    Mais, à ma connaissance, il vaut mieux éviter une fonction récursive, pour des raisons de performances et vu le risque de boucles infinies et de résultats aberrants.
    Tu confirmes ?
    Je confirme que les priorités ne sont pas les mêmes. Le risque de boucle infinie est le même, c'est juste que la preuve de terminaison ne se fait pas de la même manière entre un algo récursif et un algo itératif. Ce risque, ainsi que celui de "résultat aberrant", est annulé quand on code avec rigueur et méthode...
    L'algo récursif est souvent plus "élégant" et plus lisible (il peut plus facilement correspondre à une spécification directe du problème), mais il utilise plus de mémoire (pile d'appel).
    Je ne connais pas les comparaisons en terme de temps de calcul.

    Il y a des langages (prolog) qui fonctionnent de manière intrinsèquement récursive.

  11. #11
    Membre éclairé
    Inscrit en
    Septembre 2006
    Messages
    685
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 685
    Points : 658
    Points
    658
    Par défaut
    J'ai essayé ton code, mais j'arrive pas obtenir le résultat souhaité, j'ai seulement 2 éléments dans le tableau.

  12. #12
    Membre éclairé
    Inscrit en
    Septembre 2006
    Messages
    685
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 685
    Points : 658
    Points
    658
    Par défaut
    Ah ça y est, c'est bon, en mettant global, ça fonctionne.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    $arr = array();
    global $arr;
    function divise($n, $d)
    {
      global $arr;
      $r = $n/$d;
      if( !is_float($r) ) {
        $arr[] = $r;
        divise($r, $d);
      }
      return $arr;
    }
    print_r(divise(128, 2));
    Merci à vous deux

  13. #13
    Membre expert

    Profil pro
    imposteur
    Inscrit en
    Avril 2003
    Messages
    3 308
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : imposteur

    Informations forums :
    Inscription : Avril 2003
    Messages : 3 308
    Points : 3 377
    Points
    3 377
    Par défaut
    Citation Envoyé par Xunil
    J'ai essayé ton code, mais j'arrive pas obtenir le résultat souhaité, j'ai seulement 2 éléments dans le tableau.
    Et c'est pas normal ? J'ai pas dû comprendre ce que tu voulais faire. Donne des spécifications précises alors.

  14. #14
    Membre expert

    Profil pro
    imposteur
    Inscrit en
    Avril 2003
    Messages
    3 308
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : imposteur

    Informations forums :
    Inscription : Avril 2003
    Messages : 3 308
    Points : 3 377
    Points
    3 377
    Par défaut
    Ca fonctionne très bien sans variable globale.
    L'utilisation de variables globales est généralement à éviter.

  15. #15
    Membre éclairé
    Inscrit en
    Septembre 2006
    Messages
    685
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 685
    Points : 658
    Points
    658
    Par défaut
    Je souhaite compléter mon tableau au fur et à mesure, ou encore concaténer une variable.

    Si j'enlève global, j'obtiens qu'un seul élément, le 1er.

    Si je laisse global, j'obtiens alors pour ce que j'ai mis ci-dessus:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Array ( [0] => 64 [1] => 32 [2] => 16 [3] => 8 [4] => 4 [5] => 2 [6] => 1 )
    Ce qui est correct.

    Mais si t'as une autre soluce sans global, je veux bien, moi non plus je n'aime pas trop l'utiliser.

  16. #16
    Membre expert

    Profil pro
    imposteur
    Inscrit en
    Avril 2003
    Messages
    3 308
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : imposteur

    Informations forums :
    Inscription : Avril 2003
    Messages : 3 308
    Points : 3 377
    Points
    3 377
    Par défaut
    Citation Envoyé par Xunil
    Je souhaite compléter mon tableau au fur et à mesure, ou encore concaténer une variable.

    Si j'enlève global, j'obtiens qu'un seul élément, le 1er.

    Si je laisse global, j'obtiens alors pour ce que j'ai mis ci-dessus:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Array ( [0] => 64 [1] => 32 [2] => 16 [3] => 8 [4] => 4 [5] => 2 [6] => 1 )
    Ce qui est correct.

    Mais si t'as une autre soluce sans global, je veux bien, moi non plus je n'aime pas trop l'utiliser.
    Il suffit d'adapter la solution que je t'ai donnée, pour mettre le nouveau nombre au début et pas à la fin, et pour ne pas insérer le dernier flottant.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    function divise($n, $d)
    {
      $r = $n/$d;
      if( !is_float($r) ) {
        $arr = divise($r, $d);
        $arr = array_merge(array($r), $arr);
        return $arr;
      }
      else {
        $arr= array();
        return $arr;
      }
    }

  17. #17
    Membre éclairé
    Inscrit en
    Septembre 2006
    Messages
    685
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 685
    Points : 658
    Points
    658
    Par défaut
    Merci, ça fonctionne, mais je comprend pas bien..

    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
     
    function divise($n, $d) 
    {  
      $r = $n/$d; 
      if( !is_float($r) ) {
        $arr = divise($r, $d); // ici, $arr, c'est une variable, ou un array() ?
        // ce qui suit en dessous est exécuté une seule fois ou à chaque récursivité ?
        $arr = array_merge(array($r), $arr); // Pourquoi utiliser array_merge ?
        return $arr; 
      }  
      else {
        $arr= array();
        return $arr; 
      } 
    }
    Merci.

  18. #18
    Membre expert

    Profil pro
    imposteur
    Inscrit en
    Avril 2003
    Messages
    3 308
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : imposteur

    Informations forums :
    Inscription : Avril 2003
    Messages : 3 308
    Points : 3 377
    Points
    3 377
    Par défaut
    1. $arr, c'est une variable, qui est un tableau (array). C'est une TRES mauvaise idée d'avoir des noms de variables qui sont des mots réservés du langage.
    2. Le array_merge est exécuté à chaque étape de l'algorithme, sauf à la dernière. Il sert à ajouter quelque chose dans le tableau $arr. On aurait pu le remplacer juste par $arr[] = $r, mais ça aurait mis les éléments dans l'ordre inverse de ce que tu demandais (en ajoutant $r à la fin à chaque fois). Alors j'ai utilisé array_merge, qui concatène deux tableaux, pour ajouter $r au début.

  19. #19
    Membre éclairé
    Inscrit en
    Septembre 2006
    Messages
    685
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 685
    Points : 658
    Points
    658
    Par défaut
    Ok, c'est un peu plus clair.

    Merci de tes explications

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

Discussions similaires

  1. Réponses: 1
    Dernier message: 13/04/2015, 11h17
  2. comment garder en mémoire la valeur d'une variable
    Par java250r dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 12/04/2012, 18h53
  3. Réponses: 2
    Dernier message: 15/07/2011, 22h48
  4. Réponses: 5
    Dernier message: 19/11/2010, 12h28
  5. Recherche une valeur d'une cellule dans une colonne d'une autre feuille
    Par kourria dans le forum Macros et VBA Excel
    Réponses: 8
    Dernier message: 21/06/2007, 13h48

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