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 :

Récursion avec while


Sujet :

Langage PHP

  1. #1
    Membre confirmé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juillet 2006
    Messages
    985
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Juillet 2006
    Messages : 985
    Points : 460
    Points
    460
    Par défaut Récursion avec while
    Bonjour,
    Je trouve la récursion avec un while plus légère qu'une fonction qui appelle elle même. Quelqu'un pourrait m'apprendre ce principe par la boucle while ?
    Une application simple serait la bienvenue.

    Merci d'avance...

  2. #2
    Expert éminent sénior
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    Bonjour,

    en simplifiant, la récursivité c'est le fait pour tout ou partie d'un algorithme de s'auto-exécuter.
    Et pour le coup while n'est pas récurisif, c'est une boucle qui s'éxécute tant qu'une condition est vérifiée en entrée ou sortie de boucle.

    Un peu de lecture ici
    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
     
    // RECURSIVITE
    function factorielle($x)
    {
        if($x == 0)
            return 1;
        else
            return $x*factorielle($x-1);
    }
     
    // BOUCLE
    $i = 0;
    $j = 1;
    while($i < 10) {
        $j += $i;
        $i += 1;
    }
    Est ce que tu ne parlerais pas par hasard de la transformation d'un algorithme récursif en algorithme itératif ?

  3. #3
    Membre confirmé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juillet 2006
    Messages
    985
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Juillet 2006
    Messages : 985
    Points : 460
    Points
    460
    Par défaut
    Dans ce sens :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    if ($current = $doc->getElementById($id)) {
    	while ($current = $current->parentNode) {
    	//actions		
    	}
    }
    Un autre exemple se déplacer enfant > parent > grand parent ou inversement...
    en utilisant while.

  4. #4
    Expert éminent sénior
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    Ton exemple n'est pas récursif.
    Il équivaut à dire : Tant qu'un noeud parent existe exécuter ces actions sur le parent.
    En gros, je ne vois pas trop ce que tu cherches à te faire expliquer.

    La seule chose qui pourrait nécessiter des explications c'est la transformation du récursif vers l'itératif. Parfois, ça peut être assez compliqué.

  5. #5
    Membre confirmé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juillet 2006
    Messages
    985
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Juillet 2006
    Messages : 985
    Points : 460
    Points
    460
    Par défaut
    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
    $html =  '<ul>
    	<li><a href="#">Accueil</a></li>
    	<li><a href="#">Pays</a>
    		<ul>
    			<li><a href="#">Rca</a></li>
    			<li><a href="#">Cameroun</a>
    				<ul>
    					<li><a href="#">Yaounde</a></li>
    					<li><a href="#" id="current">Douala</a>
    				</ul>
    			</li>
    			<li><a href="#">Tchad</a></li>
    		</ul>
    	</li>
    	<li><a href="#">Contact</a></li>
    </ul>';
     
    $doc = new DOMDocument;
    $doc->loadHTML($html);
     
    if ($current = $doc->getElementById('current')) {
    	while ($current = $current->parentNode) {
    		if ($current->nodeName == 'li')
    			$current->setAttribute('class', ltrim($current->getAttribute('class') . ' chemin'));
    	}
    }
     
    echo "<pre>" . htmlentities($doc->saveHTML()) . "</pre>";
    Résultat :
    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
     
    <ul>
    	<li><a href="#">Accueil</a></li>
    	<li class="chemin"><a href="#">Pays</a>
    		<ul>
    			<li><a href="#">Rca</a></li>
    			<li class="chemin"><a href="#">Cameroun</a>
    				<ul>
    					<li><a href="#">Yaounde</a></li>
    					<li class="chemin"><a href="#" id="current">Douala</a></li>
    				</ul>
    			</li>
    			<li><a href="#">Tchad</a></li>
    		</ul>
    	</li>
    	<li><a href="#">Contact</a></li>
    </ul>
    Observez le boulot de while, remonter récursivement dans l'arborescence pour appliquer des actions. C'est ce que je souhaite comprendre. Comment à chaque nœud il recherche le parent.

    moi je procéderais ainsi par une fonction récursive.
    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
     
    function getbreadcrumb(DOMDocument $doc, $checkclass, $addclass, $tag = null){
    	$return = false;
    	if ( $anchor = $doc->getElementById($checkclass) ) {
    		$parent = $anchor->parentNode;
    		addclass($parent, $addclass, $tag);
    		$return = $doc->saveHTML();
    	}
    	return $return;
    }
     
    function addclass(DOMElement $node, $addclass, $tag){
    	if ( $node && $node->nodeName == $tag ) {
    		$node->setAttribute('class', $addclass);
    		//Recursively		
    		$parent = $node->parentNode; //ul
    		$parent = $parent->parentNode; //li
    		addclass($parent, $addclass, $tag);
    	}
    }
     
    $html =  '<ul>
    	<li><a href="#">Accueil</a></li>
    	<li><a href="#">Pays</a>
    		<ul>
    			<li><a href="#">Rca</a></li>
    			<li><a href="#">Cameroun</a>
    				<ul>
    					<li><a href="#">Yaounde</a></li>
    					<li><a href="#" id="current">Douala</a>
    				</ul>
    			</li>
    			<li><a href="#">Tchad</a></li>
    		</ul>
    	</li>
    	<li><a href="#">Contact</a></li>
    </ul>';
    libxml_use_internal_errors(false);
    $doc = new DOMDocument();
    $doc->loadHTML($html);
    $html = getbreadcrumb($doc, 'current', 'chemin', 'li');
    echo $html;
    C'est plus long. while fait un sale boulot que ne comprend pas.

  6. #6
    Expert éminent sénior
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    Citation Envoyé par okoweb Voir le message
    Observez le boulot de while, remonter récursivement dans l'arborescence pour appliquer des actions.
    Non, while ne remonte pas récursivement l'arborescence. Il ne s'appelle pas lui-même : la boucle initiale s'exécute tant qu'il y a un parent. C'est totalement différent.
    while remonte un à un les noeuds. Je tiens encore à te rappeler qu'une fois lancée, c'est la même boucle qui s'exécute tant qu'une condition est vérifiée.

    La seule subtilité réside dans l'initialisation de la boucle while et dans ses appels successifs (et pas récursifs, hein) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while ($current = $current->parentNode) { ... }
    Deux choses sont faites : on se positionne sur le noeud parent et on le transforme en noeud courant. C'est tout.
    Ensuite le code s'exécute sur le nouveau noeud courant. Et ainsi de suite tant qu'il existe un noeud parent au noeud courant.

    C'est plus clair ?

  7. #7
    Expert éminent
    Avatar de Benjamin Delespierre
    Profil pro
    Développeur Web
    Inscrit en
    Février 2010
    Messages
    3 929
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2010
    Messages : 3 929
    Points : 7 762
    Points
    7 762
    Par défaut
    Le même algo en reccursif:
    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
    <?php
     
    $html = <<< HTML
    <ul>
        <li><a href="#">Accueil</a></li>
        <li><a href="#">Pays</a>
            <ul>
                <li><a href="#">Rca</a></li>
                <li><a href="#">Cameroun</a>
                    <ul>
                        <li><a href="#">Yaounde</a></li>
                        <li><a href="#" id="current">Douala</a>
                    </ul>
                </li>
                <li><a href="#">Tchad</a></li>
            </ul>
        </li>
        <li><a href="#">Contact</a></li>
    </ul>
    HTML;
     
    $doc = new DOMDocument;
    $doc->loadHTML($html);
     
    function add_class ($node, $class, $nodename) {
        if (!$node)
            return;
     
        if ($node->nodeName == $nodename)
            $node->setAttribute('class', ltrim($node->getAttribute('class') . " $class"));
     
        add_class($node->parentNode, $class, $nodename);
    }
     
     
    ($current = $doc->getElementById('current')) && add_class($current, 'chemin', 'li');
     
    echo "<pre>" . htmlentities($doc->saveHTML()) . "</pre>";
    La récursivité n'apporte rien dans ce cas, autant utiliser un bon vieil algo itératif classique

  8. #8
    Membre confirmé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juillet 2006
    Messages
    985
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Juillet 2006
    Messages : 985
    Points : 460
    Points
    460
    Par défaut
    Citation Envoyé par rawsrc Voir le message
    C'est plus clair ?
    Oui.

  9. #9
    Membre confirmé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juillet 2006
    Messages
    985
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Juillet 2006
    Messages : 985
    Points : 460
    Points
    460
    Par défaut
    Merci à vous tous !

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

Discussions similaires

  1. probleme avec while Perl
    Par imorum dans le forum Langage
    Réponses: 2
    Dernier message: 21/01/2007, 19h03
  2. Problème avec while et paramètres
    Par mittim dans le forum Linux
    Réponses: 4
    Dernier message: 08/08/2006, 10h47
  3. Noob a un pobleme avec While .
    Par Sobuga dans le forum C
    Réponses: 14
    Dernier message: 04/08/2006, 07h50
  4. Probleme avec WHILE
    Par beb30 dans le forum C
    Réponses: 14
    Dernier message: 05/04/2006, 14h40
  5. [Tableaux] problème avec while
    Par zimotep dans le forum Langage
    Réponses: 3
    Dernier message: 11/09/2005, 10h30

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