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 :

Fonction récursive - récupérer le résultat sans ECHO


Sujet :

Langage PHP

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Février 2008
    Messages
    88
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 88
    Points : 40
    Points
    40
    Par défaut Fonction récursive - récupérer le résultat sans ECHO
    Bonjour,

    J'ai une fonction récursive qui retourne toutes les combinaisons possibles entres plusieurs tableaux, la voici:


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    function produit_croise($pile,$prefixe ='') // toutes les combinaisons possibles entre plusieurs tableaux
    {
    	if(count($pile)==0)
    		echo $prefixe.'<br/>';
    	else {
    		$tableau_courant = array_pop($pile); // on enleve un tableau parmis les tableaux, donc taille de pile a diminué de 1
    		foreach($tableau_courant as $e)
    			produit_croise($pile,$prefixe.$e);
    	}
    }
    Le problème est que le echo ne me convient pas.
    J'aimerai pouvoir stocker chaque combinaison dans un tableau pour pouvoir faire ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    $tabCombinaison = produit_croise($tab_valeurs);
     
    for($i=0;$i<(count($tabCombinaison);++$i)
    {
    echo $tabCombinaison[$i];
    }
    Est ce possible de stocker des valeurs dans une variable dans une fonction récursive ? Si oui comment s'il vous plait ?

    Merci beaucoup.

  2. #2
    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
    J'ai déjà fait cette fonction par le passé, la voilà:

    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
    /**
     * @brief Calculates the cartesian product of any number of array in parameter
     *
     * @ingroup Functions
     * @param mixed $a
     * @param mixed $b [...]
     * @return array
     */
    function array_cartesian_product () {
        if (!$c = func_num_args())
            return array();
     
        if ($c == 1) {
            foreach ((array)func_get_arg(0) as $v)
                $r[] = (array)$v;
            return $r;
        }
     
        $a = func_get_args();
        $f = array_shift($a);
        $s = call_user_func_array(__FUNCTION__, $a);
     
        foreach ((array)$f as $v) {
            foreach ($s as $w) {
                array_unshift($w, $v);
                $r[] = $w;
            }
        }
     
        return $r;
    }
    Exemple: le jeu de cartes
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    $colors  = array('pique', 'trèfle', 'carreau', 'coeur');
    $numbers = array(2,3,4,5,6,7,8,9,10,'valet','dame','roi','as');
     
    $deck = array_cartesian_product($numbers, ' de ', $colors);
    $deck = array_map('implode', $deck);
     
    shuffle($deck);
     
    for ($i=0; $i<5; $i++)
      echo array_pop($deck) . '<br />';

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Février 2008
    Messages
    88
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 88
    Points : 40
    Points
    40
    Par défaut
    Merci mais pourquoi lorsque je fais ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    $colors  = array('pique', 'trèfle');
    	$numbers = array(1,2);
    	$var3 = array('testA');
    	$var4 = array('test1','test2');
     
    	$deck = array_cartesian_product($numbers, '-', $colors, '-', $var3, '-', $var4);
    	$deck = array_map('implode', $deck);
     
    for ($i=0; $i<count($deck); $i++)
    	  echo array_pop($deck) . '<br />';
    le résultat qui s'affiche est celui ci (il manque 4 résultats) ?:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    2-trèfle-testA-test2
    2-trèfle-testA-test1
    2-pique-testA-test2
    2-pique-testA-test1
    Ca devrait être:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    1-trèfle-testA-test2
    1-trèfle-testA-test1
    1-pique-testA-test2
    1-pique-testA-test1
    2-trèfle-testA-test2
    2-trèfle-testA-test1
    2-pique-testA-test2
    2-pique-testA-test1
    Merci encore pour ton aide.

  4. #4
    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
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    for ($i=0; $i<count($deck); $i++)
    	  echo array_pop($deck) . '<br />';


    array_pop renvoie le dernier élément du tableau et l'efface donc ça modifie le count.

    Si tu utilisais un foreach, tu verrai que toutes les entrées sont là
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    foreach ($deck as $value) echo $value . '<br />';

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Février 2008
    Messages
    88
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 88
    Points : 40
    Points
    40
    Par défaut
    Oh mais quel nul, je n'ai pas vu le array_pop :o Je cherchais l'erreur plus haut sans me soucier que j'avais mis array_pop lol.
    Merci, je ne vois pas plus loin que le bout de mon nez.

    J'ai une dernière question (promis ! je ne t'embête plus après).

    En fait mes tableaux sont sous cette forme:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    $tableau[20][0]='A';
    $tableau[20][1]='B';
    $tableau[20][2]='C';
    $tableau[43][0]='Blabla';
    $tableau[43][1]='Huhu';
    $tableau[50][0]=322;
    $tableau[60][0]='ZE';
    $tableau[60][1]='TY';
    //etc........jusqu'à je ne sais où
    Il s'agit en réalité du même tableau , mais multidimensionnel (car ca m'arrange dans mon cas).

    Ainsi il faudrait que je puisse utiliser ta fonction comme ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $deck = array_cartesian_product($tableau[20], '-', $tableau[43], '-', $tableau[50], '-',$tableau[60]);
    $deck = array_map('implode', $deck);
    Le problème c'est que je ne connais pas combien de tableau je vais avoir ( ou plutot de dimension je vais avoir (j'espère que je m'exprime bien :/) et mon tableau n'a pas de clé qui se suivent les unes à la suite des autres (Cf: 20,43,50,60) .

    Je sais que c'est pas évident mais il doit bien y avoir une solution ?

    Ca sauverait ma journée (voir ma semaine) si j'arrivais à avoir une solution à ce problème

  6. #6
    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
    bah c'est pas dur:
    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
    $arr[1][] = 1;
    $arr[1][] = 2;
    $arr[1][] = 3;
    $arr[2][] = 1;
    $arr[2][] = 2;
    $arr[2][] = 3;
    $arr[3][] = 1;
    $arr[3][] = 2;
    $arr[3][] = 3;
    $arr[4][] = 1;
    $arr[4][] = 2;
    $arr[4][] = 3;
     
    $mix = call_user_func_array('array_cartesian_product', $arr);
     
    var_dump($mix);

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Février 2008
    Messages
    88
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 88
    Points : 40
    Points
    40
    Par défaut
    En effet, je suis désolé je ne connais pas très bien les fonctions un peu moins utilisée (plus complexe) sur PHP comme call_user_func_array().

    Par contre je ne peux plus avoir mes combinaisons séparées par des tirets (-).

    Par exemple au lieu de s'afficher ça:

    2-trèfle-testA-test2
    2-trèfle-testA-test1
    2-pique-testA-test2
    2-pique-testA-test1

    il s'affiche:

    2trèfletestAtest2
    2trèfletestAtest1
    2piquetestAtest2
    2piquetestAtest1

    Voila, après ceci ce sera tout, tu m'as grandement aidé et je t'en remercie énormément !

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Février 2008
    Messages
    88
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 88
    Points : 40
    Points
    40
    Par défaut
    Bon j'ai en fait modifier ta fonction pour créer les combinaison, ainsi je n'ai pas eu trop de difficultés.


    Merci beaucoup et merci pour ta patience !

  9. #9
    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
    Il n'y avait pourtant pas besoin de modifier array cartesian product pour ajouter des tirets:

    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
    $arr[1][] = 1;
    $arr[1][] = 2;
    $arr[1][] = 3;
    $arr[3][] = 1;
    $arr[3][] = 2;
    $arr[3][] = 3;
    $arr[5][] = 1;
    $arr[5][] = 2;
    $arr[5][] = 3;
    $arr[7][] = 1;
    $arr[7][] = 2;
    $arr[7][] = 3;
     
    $mix = call_user_func_array('array_cartesian_product', $arr);
     
    array_walk($mix, function (&$item, $key) {
    	$item = implode('-', $item);
    });
     
    var_dump($mix);

  10. #10
    Membre du Club
    Profil pro
    Inscrit en
    Février 2008
    Messages
    88
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 88
    Points : 40
    Points
    40
    Par défaut
    Je ne connaissais pas array_walk(), merci.

    Par contre

    J'ai mis le topic en résolu car c'est le cas mais pourquoi lorsque je mets une 20 ene de valeur dans ta fonction je me retrouve avec cette erreur fatal:

    Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 64 bytes)

    C'est embêtant car du coup si j'ai 50 valeurs la fonction ne marche plus ?
    Ca m'embete de modifier le php.ini, surtout qu'en mutualisé OVH ne ne pense pas pouvoir modifier ca (question de droit).

    Désolé pour le dérangement :/

  11. #11
    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
    C'est assez simple en fait et c'est le défaut de tous les algos récursifs: la consommation mémoire augment exponentiellement avec le nombre d'ensembles à traiter.

    Dans le cas de notre fonction, si on utilise 10 tableaux de 10 valeurs, on se retrouve avec un tableau de sortie contenant 10 milliards de valeurs, ce qui est énorme. S'il s'agit d'entiers, ça nous fait (10^10)x32b soit ~37Go de données (quand même), et je ne parle pas de toutes les variables intermédiaires...

    Il faut donc éviter de traiter des jeux de données trop importants.

  12. #12
    Membre du Club
    Profil pro
    Inscrit en
    Février 2008
    Messages
    88
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 88
    Points : 40
    Points
    40
    Par défaut
    C'est vraiment embêtant du coup car il va falloir que je limite mes ambitions.

    En tout cas merci encore ce fut enrichissant

    Bonne journée

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

Discussions similaires

  1. Récupérer le résultat d'une fonction récursive
    Par baggie dans le forum Langage
    Réponses: 2
    Dernier message: 04/02/2011, 10h06
  2. Exécuter une fonction et récupérer le résultat
    Par coraziari_l dans le forum Servlets/JSP
    Réponses: 1
    Dernier message: 14/01/2008, 16h56
  3. Récupérer le résultat d'une fonction dans une balise html
    Par Hayato dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 19/06/2006, 17h04
  4. Réponses: 6
    Dernier message: 08/06/2006, 10h07
  5. Fonction : récupérer le résultat
    Par cristolb dans le forum ASP
    Réponses: 8
    Dernier message: 30/08/2005, 11h38

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