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 :

[Système] Récursivité et itération [Fait]


Sujet :

Langage PHP

  1. #1
    Membre éclairé
    Avatar de Floréal
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    456
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 456
    Points : 849
    Points
    849
    Par défaut [Système] Récursivité et itération
    Voila, je me suis un peu creusé la tête pour trouver comment lister les dossiers, sous dossiers, sous sous dossiers, etc. Et j'ai trouvé: J'ai utilisé une fonction récurcive:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    function listeLesDossiers($d)
    {
    	$monDossier = opendir($d);
    	$ch = $d.'/';
    	printf('%s<br />', $ch);
    	while($tmp = readdir($monDossier))
    	{
    		if($tmp != '..' && $tmp != '.' && is_dir($ch.$tmp))
    		listeLesDossiers($ch.$tmp);
    	}
    	return;
    }
    sous unix, il faut l'appeller qu'une seule fois:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    listeLesDossiers('/Répertoire qu'un veut lister'); //ou
    Si on veut lister tout le système de fichier (déconseillé pour raison de
    sécurité et de temps d'exécution)

    sous windows dans une boucle cemme celle là:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    for($lecteur = 'A';  $lecteur <= 'Z'; $lecteur++)
    {
    	$chemin = $lecteur.':';
    	if(is_dir($chemin))
    	{
    		listeLesDossiers($chemin);
    	}
    }
    J'espère que ca pourra aider. J'essayerai de mettre d'autres exemples de fonction récurcives si je suis confronté à ce cas de figure.

  2. #2
    Membre éclairé
    Avatar de genova
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    487
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 487
    Points : 790
    Points
    790
    Par défaut
    Oui la récursivité est trop peu employée alors que c'est pourtant une méthode propre et rapide. A ce propos j'avais fait un tutorial sur l'iteratif et le récursif je le poste ici pour ettofer ton sujet (je poste le tuto cache comme il était) :

    Iteratif et recursif
    • > Introduction_______________________///

      L'iteratif et le recursif sont deux facons de programmer, tres utiles, que je vais tenter de vous expliquer. Ces deux types sont utiles notamment pour effectuer un certain nombre de fois (qu'on ne peut déterminer a l'avance) un certain script, et donc permettent une optimisation du code. Si l'iteratif est relativement facile à comprendre, je vous conseille de passer un peu plus de temps sur le recursif qui est un concept pas forcement évident au début. Une fois que vous maîtriserez ces deux concepts vous aurez fait une belle avancée.

      > Programmation iterative_____________///

      La programmation iterative est une méthode permettant de répéter un certain nombre d'action un certain nombre de fois, à l'aide d'une boucle et d'une variable qui s'incrémentera à chaque passage (on appelle généralement cette variable $i). La façon la plus simple pour apprendre est avec un exemple. Nous allons créer une fonction my_pow($nombre, $puissance) qui permettra d'élever le nombre $nombre à la puissance $puissance. Mathématiquement que se passe t'il ?
      Si on prend 3 puissance 4 par exemple, cela équivaut à 3 * 3 * 3 * 3. Nous allons donc répéter 4 fois ($puissance) la multiplication de $nombre ( qui vaut 3 dans notre exemple) par lui meme. Voici la fonction finale:
      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
      function my_pow($nombre, $puissance)
      {
         // Par convention si la puissance est negative on retourne 0 ici, en effet nous
         // ne travaillerons ici que sur les entiers.
         if ($puissance < 0)
         {
            return (0);
         }
       
         // On donne comme valeur au $ resultat 1 a la base, comme ca si jamais on a un nombre
         // a la puissance 0 la boucle ne se passera pas et on renvera 1, sachant qu'un
         // nombre puissance 0 vaut 1
         $resultat = 1;
       
         // On lance la boucle, a chaque passage on multiplie $resultat par le nombre,
         // et cela tant que $i est inferieur a $puissance
         for ($i = 0; $i < $puissance; $i++)
         {
            $resultat *= $nombre; // equivaut a $resultat = $resultat * $nombre;
         }
         return ($resultat);
      }
      Pour l'utilisation, faites :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      // Affichera 3 a la puissance 4, soit 81
      echo my_pow(3, 4);

      > Programmation recursive____________///

      La programmation recursive est une autre méthode permettant de répéter un nombre indéterminé de fois une action. on crée une fonction qui va effectuer une action. Dans cette fonction nous plaçons une condition. Si cette condition est vraie on appelle la fonction à nouveau en son sein même, si c'est faux on sort avec un return. On va ainsi répéter la fonction tant que la condition est vraie. Pour bien comprendre nous allons étudier deux exemples significatifs. Le premier est une fonction qui permet de lister le contenu d'un répertoire, et de tout ses sous-répertoires, ainsi que tout les sous-répertoires des sous-répertoires, etc... Tant qu'il y a des répertoires quoi , On va donc créer une fonction my_dossier($dir) qui va lister le répertoire qu'il prend comme paramètre. Si on rencontre un répertoire dans ce listage, on appelle à nouveau la fonction avec ce répertoire rencontré, etc... Voici le code:
      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
      function my_dossier($dir)
      {
         // On ouvre le dossier
         $open = opendir($dir);
       
         // On liste le dossier
         while ($file = readdir($open))
         {
            // Si le fichier parcouru est un dossier...
            if (is_dir($dir . $file))
            {
               // ...alors on affiche ce dossier en gras et on repete la fonction
               // pour ce dossier.
               echo '<b>Dossier :: ' . $dir . $file . '/</b><br />';
               my_dossier($dir . $file . '/');
            }
            else
            {
               // Sinon on affiche en normal le fichier
               echo 'Fichier :: ' . $dir . $file . '<br />';
            }
         }
      }
      Bien entendu je ne prend pas en compte pour ce premier exemple l'indentation (tabulation) entre les différents dossiers, je vous laisse le faire

      Pour le second exemple nous allons recoder la fonction print_r($tab) qui affiche récursivement un tableau de données. Nous allons donc parcourir les éléments de ce tableau, et à chaque sous-tableau rencontré on répète la fonction.
      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
      function my_print_r($tab)
      {
         // On est au tout debut d'un tableau donc on affiche array(
         echo 'array(<br />';
       
         // On parcourt le tableau
         while (list($key, $value) = each($tab))
         {
            // Si la valeur courante est un tableau...
            if (is_array($value))
            {
               // On parcourt le sous tableau rencontre
               my_print_r($value);
            }
            else
            {
               // On affiche la cle et la valeur courante
               echo '\'' . $key . '\' => \'' . addslashes($value) . '\',<br />';
            }
       
         // On a fini de parcourir le tableau...
         echo '),<br />';
         }
      }
      Je vous laisse là aussi paginer les tabulations.
      Bon allez pour finir un petit exercice pas bien compliqué, essayez de refaire la fonction de l'exercice 1, la fonction des puissances qu'on a codé itérativement, refaites la en récursif Si vous voulez la solution demandez-la moi par MP, mais essayez de la coder au moins.


      > Conclusion________________________///

      Si vous découvrez ces deux méthodes, particulièrement le récursif, je vous conseille à tout prix de comprendre les exemples et de vous entraîner avec d'autres applications (sous-forums, sous-groupes, etc...). Pour toute question n'hésitez pas à m'envoyer un MP ou bien poster dans le forum d'aide au dévelopement ou coding.

  3. #3
    Membre régulier
    Avatar de titoon
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    71
    Détails du profil
    Informations personnelles :
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Janvier 2005
    Messages : 71
    Points : 86
    Points
    86
    Par défaut
    A noter que les algos récursifs sont dans la pluspart des cas plus gourmands en ressources (temps de calcul et mémoire utilisée) que les équivalents itératifs...
    Donc, si vous avez le choix, utilisez des boucles
    (Et si vous aimez la récursivité, mettez vous au scheme )

  4. #4
    Membre éclairé
    Avatar de genova
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    487
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 487
    Points : 790
    Points
    790
    Par défaut
    Plus gourmands oui surement, mais plus lents je ne suis pas sur. tout dépend de la fonction après c'est sur. mais de toute façon parfois il n'y a pas le choix on est obligé de passer par du recrusif (par exemple le listage des sous dossiers, printr_r, etc ... je ne vois pas comment le faire en itératif).

  5. #5
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    Surtout qu'en PHP, la récursivité est très mal gérée.
    Enfin ça m'empêche pas de l'utiliser massivement. C'est un concept de programmation indispensable, c'est d'ailleurs pour ça que PHP est tant critiqué...

  6. #6
    Nouveau membre du Club
    Inscrit en
    Mai 2002
    Messages
    21
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 21
    Points : 25
    Points
    25
    Par défaut
    Citation Envoyé par loufoque
    Surtout qu'en PHP, la récursivité est très mal gérée.
    Cela dit en php5 ça doit etre mieux géré, il existe des iterateurs dont un pour le parcours de dossier.

    http://fr3.php.net/manual/fr/ref.spl.php

  7. #7
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    Ça ne change rien du tout...
    Recursion is the mechanism in which a function calls itself. This is a powerful feature which can make something complex something simple. An example of a function using recursion is quicksort. Unfortunately, PHP is not good at recursion. Zeev, one or the developers of PHP, says this: "PHP 4.0 (Zend) uses the stack for intensive data, rather than using the heap. That means that its tolerance recursive functions is significantly lower than that of other languages." See bug 1901. This is a poor excuse. Every programming language should provide good recursion support.

  8. #8
    Membre éclairé
    Avatar de genova
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    487
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 487
    Points : 790
    Points
    790
    Par défaut
    D'un autre côté s'ils pouvaient améliorer la récursivité je supôse que ca aurait été déjà fait il doit donc y avoir un truc qui empèche de rendre la récursivité optimale

  9. #9
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    Oui, c'est expliqué.
    Ils préférent faire en sorte que la récursivité soit plus rapide mais limitée en terme de niveau d'imbrication.

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

Discussions similaires

  1. Réponses: 0
    Dernier message: 19/04/2012, 22h36
  2. Itérations et convergence dans un système stéréoscopique
    Par neoirto dans le forum Mathématiques
    Réponses: 8
    Dernier message: 06/08/2009, 19h45
  3. Récursivité dans un système "monnayeur"
    Par TiteFleur dans le forum Algorithmes et structures de données
    Réponses: 7
    Dernier message: 17/10/2006, 18h47
  4. IA avec le système de note
    Par scorpiwolf dans le forum C
    Réponses: 4
    Dernier message: 06/05/2002, 12h13

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