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 :

Générer toutes les combinaisons possibles


Sujet :

Langage PHP

  1. #1
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2011
    Messages
    273
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2011
    Messages : 273
    Points : 152
    Points
    152
    Par défaut Générer toutes les combinaisons possibles
    Bonsoir

    Je cherche à créer un code PHP qui permet de générer toutes les combinaisons possibles parmi une chaîne de caractères. Par exemple si la chaîne est abc les combinaisons sont aaa bbb ccc aab aac bac bca cac cbc ccb cca et j'en sais surement oublié. Chaque combinaison devra être unique à la fin de la génération donc il ne doit pas y avoir par exemple 2 fois bca. Cela peut se faire de n'importe quelle façon tant qu'à la fin j'ai toutes les combinaisons qui arrivent une par une (pour les placer par exemple dans une base de données à chaque fois que la suivante arrive).

    J'ai déjà un code C# qui fonctionne parfaitement

    Code c# : 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
    public void TacheA(){
        string sChaineMD5 = "";
        string sChaineSHA256 = "";
        string sChaine = "";
        maRequeteInsererDonnees = "INSERT INTO `logiciel`.`table` (`fldChaine`) VALUES (@Chaine)";
        maCommandeInsererDonnees = new MySqlCommand(maRequeteInsererDonnees, maConnexion);
        maCommandeInsererDonnees.Parameters.Add(new MySqlParameter("@Chaine", MySqlDbType.String, 30));
        foreach (var s in CreateCombinations("abcdefghijklmnopqrstuvwxyz0123456789", 4)){
            sChaine = s;
            try { maCommandeInsererDonnees.Parameters["@Chaine"].Value = sChaine; }
            catch { };
            try{
                maCommandeInsererDonnees.Connection.Open();
                maCommandeInsererDonnees.ExecuteScalar();
            }
            catch{
            }
            finally{
                maCommandeInsererDonnees.Connection.Close();
            }
        }
        ThreadA.Interrupt();   // Car TacheA est en faite un thread pour éviter que le logiciel se bloque 
        MessageBox.Show("Terminé");
    }

    Cela permet de mettre dans la base toutes les chaînes de 4 caractères (pas plus pas moins) que l'on peut former avec abcdefghijklmnopqrstuvwxyz0123456789.

    Je l'ai d'abord écris en C# car c'est le langage que je maîtrise le mieux.

    J'ai ensuite essayé en PHP :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    function combinaisons(array $tab, $taille){
        foreach ($c as $tab){	
    	if($taille ==1)
    		return $c;
    	else{
    		foreach ($s as combinaisons($tab, $taille - 1))
    		return $c + $s;
    	}
    }
    }
    Bien sûr je commence par le stricte minimum mais j'ai déjà un problème.

    Fatal error: Can't use function return value in write context in C:\UwAmp\www\new.php on line 75
    La ligne 75 étant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    foreach ($s as combinaisons($tab, $taille - 1))
    En plus je ne sais même pas si le code PHP peut fonctionner. Le C# a été testé avec succès.

    Merci de m'aider

  2. #2
    Modérateur
    Avatar de sabotage
    Homme Profil pro
    Inscrit en
    Juillet 2005
    Messages
    29 208
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juillet 2005
    Messages : 29 208
    Points : 44 155
    Points
    44 155
    Par défaut
    le foreach PHP a les arguments dans l'autre sens.
    http://php.net/manual/fr/control-structures.foreach.php
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

  3. #3
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2011
    Messages
    273
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2011
    Messages : 273
    Points : 152
    Points
    152
    Par défaut
    Merci d'avoir vu cette erreur mais malheureusement c'est toujours pas bon.

    Voici ma fonction actuellement :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    function combinaisons(array $tab, $taille){
     
    foreach ($tab as $c)
    {	
    	if($taille ==1)
    		return $c;
    	else
    	{
    		foreach (combinaisons($tab, $taille - 1) as $s)
    		return $c + $s;
    	}
    }
    }
    Et je la lance avec :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ii = array("a", "b");
    combinaisons($ii, 2);
    Et j'ai le message d'erreur "Warning: Invalid argument supplied for foreach() in C:\UwAmp\www\new.php on line 75"

  4. #4
    Modérateur
    Avatar de sabotage
    Homme Profil pro
    Inscrit en
    Juillet 2005
    Messages
    29 208
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juillet 2005
    Messages : 29 208
    Points : 44 155
    Points
    44 155
    Par défaut
    Ta fonction combinaison ne renvoit pas un tableau.
    $c et $s étant des chaines $c + $s ne fonctionne pas.
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

  5. #5
    Membre émérite

    Profil pro
    Inscrit en
    Mai 2008
    Messages
    1 576
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 1 576
    Points : 2 440
    Points
    2 440
    Par défaut
    La récursivité ne fonctionne pas car le premier argument de combinaison doit être un array, et tes return retournent un scalaire.
    Edit: oups, doublon avec Sabotage :-)

  6. #6
    Membre émérite

    Profil pro
    Inscrit en
    Mai 2008
    Messages
    1 576
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 1 576
    Points : 2 440
    Points
    2 440
    Par défaut
    Par ailleurs, le code .Net que tu montres n'a rien à voir avec le code PHP, donc on ne peut pas comparer. Il faudrait le contenu de CreateCombinations()

  7. #7
    Membre expert
    Avatar de Dendrite
    Femme Profil pro
    Développeuse informatique
    Inscrit en
    Juin 2008
    Messages
    2 129
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 58
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeuse informatique
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Juin 2008
    Messages : 2 129
    Points : 3 627
    Points
    3 627
    Billets dans le blog
    8
    Par défaut
    Suis curieuse de voir ta solution.
    Moi qui ai beaucoup de mal avec la récursivité, je m'en suis sortie en faisant du découpage logique : 3 sous-fonctions appellée par la fonction principale.
    function permut($tab,$i,$j) qui retourne un tableau permuté selon les indices passés en param, false si la permutation n'a pas été possible ou nécessaire
    function fromArrayToString($tab)
    function fromStringToArray($tab)
    La fonction mère appelle les trois autres et le rendu semble bon.
    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
     
    $permutations=permutations('azrb');
    //exemple avec la chaine azrb ou n'importe quelle chaine de n'importe quelle longueur
    Array
    (
        [0] => azrb
        [1] => zarb
        [2] => rzab
        [3] => bzra
        [4] => zarb
        [5] => arzb
        [6] => abrz
        [7] => rzab
        [8] => arzb
        [9] => azbr
        [10] => bzra
        [11] => abrz
        [12] => azbr
    )
    PDO, une soupe et au lit !
    Partir de la fin est un bon moyen de retrouver son chemin. Bibi - 2020

  8. #8
    Membre habitué
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    101
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 101
    Points : 144
    Points
    144
    Par défaut
    Bonjour,

    J'ai essayer en recursif, je trouve ça :

    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
    <?php
    function combinaisons($chaine, $prefix = '') {
    	if(strlen($chaine) == strlen($prefix))
    		return array($prefix);
    	$caracteres = str_split($chaine, 1);
    	$combinaisons = array();
    	foreach($caracteres as $caractere) {
    		$solutions = combinaisons($chaine, $prefix.$caractere);
    		foreach($solutions as $solution)
    			array_push($combinaisons, $solution);
    	}
    	return $combinaisons;
    }
    $combinaisons = combinaisons('abc');
    echo '<pre>';
    print_r($combinaisons);

  9. #9
    Membre habitué
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    101
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 101
    Points : 144
    Points
    144
    Par défaut
    Et puisque cette fonction peut potentiellement générer des Array énormes si on l'utilise avec des chaînes longues, une version avec un générateur permettra d'économiser de la mémoire :

    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
    <?php
     
    function combinaisons($chaine, $prefix = '') {
     
    	if(strlen($chaine) == strlen($prefix)) {
    		yield $prefix;
    		return;
    	}
     
    	$caracteres = str_split($chaine, 1);
     
    	foreach($caracteres as $caractere) {
     
    		$solutions = combinaisons($chaine, $prefix.$caractere);
     
    		foreach($solutions as $solution)
    			yield $solution;
     
    	}
     
    }
     
    $combinaisons = combinaisons('abc');
     
    foreach($combinaisons as $combinaison)
    	echo $combinaison.'<br />';

  10. #10
    Membre expert
    Avatar de Dendrite
    Femme Profil pro
    Développeuse informatique
    Inscrit en
    Juin 2008
    Messages
    2 129
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 58
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeuse informatique
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Juin 2008
    Messages : 2 129
    Points : 3 627
    Points
    3 627
    Billets dans le blog
    8
    Par défaut
    Merci Yellu.
    J'essaie de faire moi-même et puis je verrai après ta solution.
    Déjà, en faisant un truc bien manuel sur 4 chaînes imbriquées (non optimisées, je sais - c'est juste pour me familiariser avec la récursivité).
    Je vois mieux ce que je mettrai dans ma 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
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
     
    function permutChaine($string,$i,$j){
    	if(is_string($string) && $i!=$j && $i>=0 && $i<strlen($string) && $j>=0 && $j<strlen($string)){
    		$temp=$string[$i];
    		$string[$i]=$string[$j];
    		$string[$j]=$temp;
    		return $string;
    	}
    	return false;
    }
     
    function permutations($string){
    	$p=array();
    	$p[]=$string;//avant de permuter, on retient la premiere chaine
    	for($i=0;$i<4;$i++){
    		for($j=0;$j<4;$j++){//ij
    			$foo1=permutChaine($string,$i,$j);
    			if( $foo1 !== false){
    				if(! in_array($foo1,$p)){
    					$p[]=$foo1;
    				}
    				for($k=0;$k<4;$k++){//jk
    					$foo2=permutChaine($foo1,$j,$k);
    					if( $foo2 !== false){
    						if(! in_array($foo2,$p)){
    							$p[]=$foo2;
    						}
    						for($l=0;$l<4;$l++){//kl
    							$foo3=permutChaine($foo2,$k,$l);
    							if( $foo3 !== false){
    								if(! in_array($foo3,$p)){
    									$p[]=$foo3;
    								}
    							}
    							for($m=0;$m<4;$m++){//lm
    								$foo4=permutChaine($foo3,$l,$m);
    								if( $foo4 !== false){
    									if(! in_array($foo4,$p)){
    										$p[]=$foo4;
    									}
    								}
    							}
    						}
    					}						
    				}
    			}
    		}
    	}
    	return $p;
    }
    $chars = 'abcs';
    $permutations=permutations($chars);
    echo '<pre>';
    print_r($permutations);
    echo '</pre>';
    Et celle-ci fonctionne, pas comme mon message d'avant.
    4 caractères = factoriel 4.
    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
     
    Array
    (
        [0] => abcs
        [1] => bacs
        [2] => bcas
        [3] => bsca
        [4] => cbas
        [5] => cabs
        [6] => cbsa
        [7] => sbca
        [8] => sacb
        [9] => sbac
        [10] => acbs
        [11] => scba
        [12] => bcsa
        [13] => acsb
        [14] => basc
        [15] => ascb
        [16] => csab
        [17] => bsac
        [18] => asbc
        [19] => csba
        [20] => absc
        [21] => casb
        [22] => scab
        [23] => sabc
    )
    PDO, une soupe et au lit !
    Partir de la fin est un bon moyen de retrouver son chemin. Bibi - 2020

  11. #11
    Membre habitué
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    101
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 101
    Points : 144
    Points
    144
    Par défaut
    Salut Dentrite,

    Je ne trouve pas que ton code répond au besoin.

    Si je reprend le message initial, il y est énoncé :

    Par exemple si la chaîne est abc les combinaisons sont aaa bbb ccc aab aac bac bca cac cbc ccb cca et j'en sais surement oublié.
    Donc pour une chaîne de 4 ce n'est pas factorielle(4) mais puissance(4).

  12. #12
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2011
    Messages
    273
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2011
    Messages : 273
    Points : 152
    Points
    152
    Par défaut
    Bonjour

    J'avoue que je ne m'attendais pas à autant de réponses. Je vais tenter de vous répondre.

    Citation Envoyé par Tsilefy Voir le message
    Par ailleurs, le code .Net que tu montres n'a rien à voir avec le code PHP, donc on ne peut pas comparer. Il faudrait le contenu de CreateCombinations()
    Oups j'ai oublié, voici la fonction (trouvée sur un site) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
            static public IEnumerable<string> CreateCombinations(IEnumerable<char> input, int length)
            {
                foreach (var c in input)
                {
                    if (length == 1)
                        yield return c.ToString();
                    else
                    {
                        foreach (var s in CreateCombinations(input, length - 1))
                            yield return c.ToString() + s;
                    }
                }
            }
    L'avantage de cette fonction c'est qu'elle génère toutes les combinaisons à partir d'une chaîne de caractère et pour la longueur passée en paramètre, c'est justement ce que j'aimerais mais en PHP. Pourquoi choisir la longueur des combinaisons générées ? Tout simplement car si la chaîne est par exemple abcdefghijklmnopqrstuvwxyz il y a tellement de combinaisons que ça mettrait une éternité à être calculé alors que si on génère les combinaisons d'une longueur donnée (par exemple 4) cela est très rapide.


    Citation Envoyé par Yellu Voir le message
    Bonjour,

    J'ai essayer en recursif, je trouve ça :

    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
    <?php
    function combinaisons($chaine, $prefix = '') {
    	if(strlen($chaine) == strlen($prefix))
    		return array($prefix);
    	$caracteres = str_split($chaine, 1);
    	$combinaisons = array();
    	foreach($caracteres as $caractere) {
    		$solutions = combinaisons($chaine, $prefix.$caractere);
    		foreach($solutions as $solution)
    			array_push($combinaisons, $solution);
    	}
    	return $combinaisons;
    }
    $combinaisons = combinaisons('abc');
    echo '<pre>';
    print_r($combinaisons);
    Merci, cela fonctionne parfaitement mais j'aimerais (si possible) récupérer uniquement les combinaisons de la longueur que je souhaite (par exemple de 4 caractères de long même si la chaîne de départ en a 10), avec cette fonction ça me renvoie aussi le mot Array ainsi que les parenthèses ainsi que l'indice de chaque combinaison dans le tableau.

    Citation Envoyé par Yellu Voir le message
    Et puisque cette fonction peut potentiellement générer des Array énormes si on l'utilise avec des chaînes longues, une version avec un générateur permettra d'économiser de la mémoire :

    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
    <?php
     
    function combinaisons($chaine, $prefix = '') {
     
    	if(strlen($chaine) == strlen($prefix)) {
    		yield $prefix;
    		return;
    	}
     
    	$caracteres = str_split($chaine, 1);
     
    	foreach($caracteres as $caractere) {
     
    		$solutions = combinaisons($chaine, $prefix.$caractere);
     
    		foreach($solutions as $solution)
    			yield $solution;
     
    	}
     
    }
     
    $combinaisons = combinaisons('abc');
     
    foreach($combinaisons as $combinaison)
    	echo $combinaison.'<br />';
    J'ai testé cette solution mais j'ai un message d'erreur "Parse error: syntax error, unexpected T_VARIABLE in C:\UwAmp\www\new.php on line 69", la ligne 69 étant la suivante :
    J'ai l'impression qu'en PHP le mot clef yield n'existe pas.

    Citation Envoyé par Dendrite Voir le message
    Merci Yellu.
    J'essaie de faire moi-même et puis je verrai après ta solution.
    Déjà, en faisant un truc bien manuel sur 4 chaînes imbriquées (non optimisées, je sais - c'est juste pour me familiariser avec la récursivité).
    Je vois mieux ce que je mettrai dans ma 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
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
     
    function permutChaine($string,$i,$j){
    	if(is_string($string) && $i!=$j && $i>=0 && $i<strlen($string) && $j>=0 && $j<strlen($string)){
    		$temp=$string[$i];
    		$string[$i]=$string[$j];
    		$string[$j]=$temp;
    		return $string;
    	}
    	return false;
    }
     
    function permutations($string){
    	$p=array();
    	$p[]=$string;//avant de permuter, on retient la premiere chaine
    	for($i=0;$i<4;$i++){
    		for($j=0;$j<4;$j++){//ij
    			$foo1=permutChaine($string,$i,$j);
    			if( $foo1 !== false){
    				if(! in_array($foo1,$p)){
    					$p[]=$foo1;
    				}
    				for($k=0;$k<4;$k++){//jk
    					$foo2=permutChaine($foo1,$j,$k);
    					if( $foo2 !== false){
    						if(! in_array($foo2,$p)){
    							$p[]=$foo2;
    						}
    						for($l=0;$l<4;$l++){//kl
    							$foo3=permutChaine($foo2,$k,$l);
    							if( $foo3 !== false){
    								if(! in_array($foo3,$p)){
    									$p[]=$foo3;
    								}
    							}
    							for($m=0;$m<4;$m++){//lm
    								$foo4=permutChaine($foo3,$l,$m);
    								if( $foo4 !== false){
    									if(! in_array($foo4,$p)){
    										$p[]=$foo4;
    									}
    								}
    							}
    						}
    					}						
    				}
    			}
    		}
    	}
    	return $p;
    }
    $chars = 'abcs';
    $permutations=permutations($chars);
    echo '<pre>';
    print_r($permutations);
    echo '</pre>';
    Et celle-ci fonctionne, pas comme mon message d'avant.
    4 caractères = factoriel 4.
    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
     
    Array
    (
        [0] => abcs
        [1] => bacs
        [2] => bcas
        [3] => bsca
        [4] => cbas
        [5] => cabs
        [6] => cbsa
        [7] => sbca
        [8] => sacb
        [9] => sbac
        [10] => acbs
        [11] => scba
        [12] => bcsa
        [13] => acsb
        [14] => basc
        [15] => ascb
        [16] => csab
        [17] => bsac
        [18] => asbc
        [19] => csba
        [20] => absc
        [21] => casb
        [22] => scab
        [23] => sabc
    )
    Effectivement, comme a dit Yellu, cela ne correspond pas à ce que je cherche car des combinaisons telles que aaaa ou bbbb ou cccc ou aabb ou abbb ou, etc etc ne sont pas présentes.



    Etant donné que mon code C# fonctionne parfaitement, voici les 5000 premiers résultats que j'obtiens si je génère toutes les combinaisons possibles de 4 caractères de long avec la chaîne abcdefghijklmnopqrstuvwxyz0123456789. Bien sûr la fonction m'a généré la totalité mais c'est inutile de tout vous montrer, c'est toujours le même principe. Comme j'ai déjà expliqué, je peux choisir la longueur des chaînes générées donc je peux encore rajouter toutes les combinaisons de 1, 2, 3, 5, etc etc caractères de long.

    http://cjoint.com/14oc/DJhpUMYro0U.htm

    Edit : La chaîne aaaa est aussi présente, simple problème de copier/coller.

  13. #13
    Membre habitué
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    101
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 101
    Points : 144
    Points
    144
    Par défaut
    Ce que tu veux faire nécessite obligatoirement une implémentation avec yield, car la fonction peut te renvoyer un tableau beaucoup trop gros pour les conf par defaut de PHP (memory_limit).

    Voici une implémentation avec le limitateur que tu souhaites en 2e paramètre.

    yield existe bien en PHP, mets juste à jours ta version.

    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
     
     
    <?php 
     
    function combinaisons_avec_generator($chaine, $length = 0, $prefix = '') {
     
    	$length = max(0, (int) $length);
     
    	if(!$length)
    		$length = strlen($chaine);
     
    	if($length == strlen($prefix)) {
    		yield $prefix; 
    		return ;
    	}
     
    	$caracteres = str_split($chaine, 1);
     
    	foreach($caracteres as $caractere) {
     
    		$solutions = combinaisons_avec_generator($chaine, $length, $prefix.$caractere);
     
    		foreach($solutions as $solution)
    			yield $solution;
     
    	}
     
    }
     
    $combinaisons = combinaisons_avec_generator('abcdefghijklmnopqrstuvwxyz0123456789', 2);
     
    foreach($combinaisons as $combinaison)
    	echo $combinaison.'<br />';

  14. #14
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2011
    Messages
    273
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2011
    Messages : 273
    Points : 152
    Points
    152
    Par défaut
    Bonsoir

    J'ai la version 3.0.2 de UWamp et la 6.6.9 de notepad++ qui sont toutes deux les dernières versions disponibles.
    En local j'ai encore cette erreur sur la ligne du yield.

    Afin de vérifier si ça provient d'un logiciel de mon PC j'ai transféré le fichier sur mon site à l'adresse http://fan-de-mixmaster.legtux.org/new.php mais commevous le constatez il y a quand même ce message d'erreur.

    J'ai fais copier/coller de votre code, aucune erreur possible.

    Edit :
    En faite j'ai l'impression que l'erreur n'a rien à voir avec le yield ...

    Sur un autre site, j'ai vu :
    L'erreur PHP classique : le parseur PHP t'indique en fait qu'il est tombé sur une variable non déclarée . Elle n'est pas simplement vide ou non initialisée : elle n'existe pas !

    Sachant que l'erreur est :

    Parse error: syntax error, unexpected '$prefix' (T_VARIABLE) in /var/www/legtux.org/users/fan-de-mixmaster/new.php on line 75
    Avez vous une idée ?

  15. #15
    Expert éminent
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 093
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : En recherche d'emploi

    Informations forums :
    Inscription : Juin 2010
    Messages : 3 093
    Points : 6 754
    Points
    6 754
    Par défaut
    Citation Envoyé par encoremoi21258 Voir le message
    L'erreur PHP classique : le parseur PHP t'indique en fait qu'il est tombé sur une variable non déclarée . Elle n'est pas simplement vide ou non initialisée : elle n'existe pas !
    Non, ce n'est pas ça. En PHP les variables non déclarées émettent des erreurs non fatales de niveau E_NOTICE, jamais des Parse Error. C'est écrit ici.

    Sachant que l'erreur est :

    Parse error: syntax error, unexpected '$prefix' (T_VARIABLE) in /var/www/legtux.org/users/fan-de-mixmaster/new.php on line 75

    Avez vous une idée ?
    L'intervenant nommé PhP sur CommentCaMarche a mal analysé le message d'erreur. L'analyse de Alain42 a plus de chances d'être correcte : un oubli de point-virgule. Unexpected T_VARIABLE signifie qu'une variable ne peut pas se trouver à cet endroit, ce qui signifie en général que l'erreur se trouve plus haut dans le code.
    La FAQ JavaScript – Les cours JavaScript
    Touche F12 = la console → l’outil indispensable pour développer en JavaScript !

  16. #16
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2011
    Messages
    273
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2011
    Messages : 273
    Points : 152
    Points
    152
    Par défaut
    Bonjour

    Le problème c'est que sur ma page il n'y a que

    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
    <?php
     
    function combinaisons_avec_generator($chaine, $length = 0, $prefix = '') {
     
    	$length = max(0, (int) $length);
     
    	if(!$length)
    		$length = strlen($chaine);
     
    	if($length == strlen($prefix)) {
    		yield $prefix; 
    		return ;
    	}
     
    	$caracteres = str_split($chaine, 1);
     
    	foreach($caracteres as $caractere) {
     
    		$solutions = combinaisons_avec_generator($chaine, $length, $prefix.$caractere);
     
    		foreach($solutions as $solution)
    			yield $solution;
     
    	}
     
    }
     
    $combinaisons = combinaisons_avec_generator('abcdefghijklmnopqrstuvwxyz0123456789', 2);
     
    foreach($combinaisons as $combinaison)
    	echo $combinaison.'<br />';
    ?>
    J'ai beau relire le code 5 fois je ne vois pas de point virgule qui manque.
    Ce n'est pas possible que ça provient quand même du yield qui se trouve juste avant ?

    Cordialement

  17. #17
    Expert éminent
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 093
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : En recherche d'emploi

    Informations forums :
    Inscription : Juin 2010
    Messages : 3 093
    Points : 6 754
    Points
    6 754
    Par défaut
    Citation Envoyé par encoremoi21258 Voir le message
    Ce n'est pas possible que ça provient quand même du yield qui se trouve juste avant ?
    Eh bien ça me paraît furieusement probable.

    Citation Envoyé par Yellu Voir le message
    yield existe bien en PHP, mets juste à jours ta version.
    Quelle est ta version de PHP ?

    Oh et par hasard, quel est ton niveau de error_reporting ? Si l'interpréteur ne reconnaît pas yield, il va supposer que c'est une constante et générer une E_NOTICE. Si ton serveur est configuré pour ignorer les E_NOTICE, tu passes à côté de ça.

    De manière générale il est conseillé d'utiliser le niveau d'error_reporting maximal en serveur de dev, tout comme il est conseillé d'utiliser le niveau minimal en prod.
    La FAQ JavaScript – Les cours JavaScript
    Touche F12 = la console → l’outil indispensable pour développer en JavaScript !

  18. #18
    Membre habitué
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    101
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 101
    Points : 144
    Points
    144
    Par défaut
    Après une rapide recherche google, voila :
    http://php.net/manual/en/migration55.new-features.php

    Il faut donc être en version de PHP 5.5 pour que yield fonctionne.

    A noter toutefois que l’algorithme que tu demandes peut être fait sans yield (voir ma première version), mais va exploser rapidement la mémoire allouée de ton script étant donné le grand nombre de combinaisons potentielles...

    La version avec yield est donc à favoriser, c'est d’ailleurs également avec yield que la version que tu possèdes déjà avais été codée dans un autre langage.

  19. #19
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2011
    Messages
    273
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2011
    Messages : 273
    Points : 152
    Points
    152
    Par défaut
    Donc finalement l'erreur provient du yield ...

    uWamp possède la version 5.4.31 mais je peux aussi choisir la version 5.5.15 mais alors j'ai un message d'erreur qui s'affiche dans uwamp :

    httpd.exe: Syntax error on line 170 of C:/UwAmp/bin/apache/conf/httpd.conf: Cannot load C:/UwAmp/bin/php/php-5.5.15/php5apache2_4.dll into server: Le module sp\xe9cifi\xe9 est introuvable.
    Il parait que c'est une incompatibilité entre la version d'apache et celle de php. C'est certainement la raison pour laquelle l'hébergeur de mon site n'a pas encore mit en ligne la version 5.5.X.

    A suivre ....

  20. #20
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2011
    Messages
    273
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2011
    Messages : 273
    Points : 152
    Points
    152
    Par défaut
    Bonjour

    Enfin j'ai trouvé un php 5.5.X
    C'est incroyable de voir le nombre de serveurs qui ne sont pas à jour, certains ont même encore la version 5.3.X ...

    Merci pour votre aide ça fonctionne très bien.

    Bonne journée

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

Discussions similaires

  1. Générer toutes les combinaisons possibles
    Par collosus dans le forum Langage
    Réponses: 1
    Dernier message: 24/06/2013, 13h54
  2. Réponses: 0
    Dernier message: 04/02/2013, 13h03
  3. Réponses: 5
    Dernier message: 18/06/2007, 20h52
  4. Réponses: 16
    Dernier message: 20/10/2006, 16h31
  5. toutes les combinaisons possibles
    Par marocleverness dans le forum Algorithmes et structures de données
    Réponses: 6
    Dernier message: 29/05/2006, 00h11

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