2010-11-25 3 views
9

Voici mon code pour obtenir toutes les possibilités:récursion Php pour obtenir toutes les possibilités de cordes

$seq[1] = 'd'; 
$seq[2] = 'f'; 
$seq[3] = 'w'; 
$seq[4] = 's'; 

for($i = 1; $i < 5; $i++) 
{ 
    $s['length_1'][] = $seq[$i]; 
    $c1++; 

    for($i2 = $i+1; $i2 < 5; $i2++) 
    { 
     $s['length_2'][] = $seq[$i].$seq[$i2]; 
     $last = $seq[$i].$seq[$i2]; 
     $c2++; 

     for($i3 = $i2+1; $i3 < 5; $i3++) 
     { 
      $s['length_3'][] = $last.$seq[$i3]; 
      $last = $last.$seq[$i3];  
      $c3++; 

      for($i4 = $i3+1; $i4 < 5; $i4++) 
      { 
       $s['length_4'][] = $last.$seq[$i4]; 
       $c4++; 
      } 
     } 
    } 
} 

for($i = 0; $i < $c1; $i++) 
    echo $s['length_1'][$i].'<br>'; 

for($i = 0; $i < $c2; $i++) 
    echo $s['length_2'][$i].'<br>'; 

for($i = 0; $i < $c3; $i++) 
    echo $s['length_3'][$i].'<br>'; 

for($i = 0; $i < $c4; $i++) 
    echo $s['length_4'][$i].'<br>';  

Mais si je veux ajouter plus, alors je vais devoir ajouter une boucle plus. Alors, comment puis-je le faire avec récursivité? J'essaie, j'essaie, mais je ne peux vraiment pas le faire. S'il vous plaît aider et publier un exemple aussi simple que possible.

Merci.

+0

Regardez ici: http://stackoverflow.com/questions/127704/algorithm-to-return-all-combinations-of-k -elements-from-n – shamittomar

Répondre

14

Voici un simple algo. Itérer de 1 à 2 décompte (tableau) -1. À chaque itération, si j-ème bit dans une représentation binaire du compteur de boucle est égale à 1, inclure j-ième élément dans une combinaison.

Comme PHP doit pouvoir calculer 2 count (tableau) en tant qu'entier, cela ne doit jamais dépasser PHP_INT_MAX. Sur une installation PHP 64 bits, votre tableau ne peut pas contenir plus de 62 éléments, car 2 reste en dessous de PHP_INT_MAX alors que 2 le dépasse.

EDIT: Ceci calcule toutes les combinaisons possibles, pas les permutations (c'est-à-dire 'abc' = 'cba'). Il le fait en représentant le tableau original en binaire et en "comptant" de 0 à la représentation binaire du tableau complet, en construisant efficacement une liste de toutes les combinaisons uniques possibles.

$a = array('a', 'b', 'c', 'd'); 

$len = count($a); 
$list = array(); 

for($i = 1; $i < (1 << $len); $i++) { 
    $c = ''; 
    for($j = 0; $j < $len; $j++) 
     if($i & (1 << $j)) 
      $c .= $a[$j]; 
    $list[] = $c; 
} 

print_r($list); 
+1

omg, c'est tellement court. Qu'est-ce que << veut dire? –

+1

cela ne va pas tester toutes les possibilités .. par exemple si seulement aller pour [a, b] il va sortir ceci: un b ab qu'en est-il "ba"? –

+3

"ba" est le même que "ab" en termes de combinaisons ou d'ensembles. Ce que vous cherchez est permutations. –

0

Ceci est une question de permutation standard, regardez dans "permutations php" si vous avez besoin de toutes les variations de la chaîne.

3

Ici, il est:

<?php 
function combinations($text,$space) 
{ 
    // $text is a variable which will contain all the characters/words of which we want to make all the possible combinations 
    // Let's make an array which will contain all the characters 
    $characters=explode(",", $text); 
    $x=count($characters); 

    $comb = fact($x); 

    // In this loop we will be creating all the possible combinations of the positions that are there in the array $characters 

    for ($y=1; $y<= $comb; $y++) 
    { 
     $ken = $y-1; 
     $f = 1; 
     $a = array(); 
     for($iaz=1; $iaz<=$x; $iaz++) 
      { 
       $a[$iaz] = $iaz; 
       $f = $f*$iaz; 
      } 
     for($iaz=1; $iaz<=$x-1; $iaz++) 
      { 
       $f = $f/($x+1-$iaz); 
       $selnum = $iaz+$ken/$f; 
       $temp = $a[$selnum]; 
       for($jin=$selnum; $jin>=$iaz+1; $jin--) 
        { 
         $a[$jin] = $a[$jin-1]; 
        } 
       $a[$iaz] = $temp; 
       $ken = $ken%$f; 
      } 
     $t=1; 

      // Let’s start creating a word combination: we have all the necessary positions 
     $newtext=""; 

     // Here is the while loop that creates the word combination 
     while ($t<=$x) 
      { 
       $newtext.=$characters[$a[$t]-1]."$space"; 
       $t++; 
      } 
     $combinations[] = $newtext ; 
    } 

     return $combinations; 

} 

function fact($a){ 
if ($a==0) return 1; 
else return $fact = $a * fact($a-1); 
} 

$a = combinations("d,f,w,s",""); 
    foreach ($a as $v) { 
      echo "$v"."\n"; 
    } 

?> 

Sortie:

dfws 
dfsw 
dwfs 
dwsf 
dsfw 
dswf 
fdws 
fdsw 
fwds 
fwsd 
fsdw 
fswd 
wdfs 
wdsf 
wfds 
wfsd 
wsdf 
wsfd 
sdfw 
sdwf 
sfdw 
sfwd 
swdf 
swfd 

En outre, read this;

+0

utilise beaucoup de mémoire:/"Erreur fatale PHP: La taille de la mémoire autorisée de 134217728 octets épuisés (essayé d'allouer 72 octets) dans ..." – Kayvar

1

Vous pouvez le faire:

function combinations($arr) { 
    $combinations = array_fill(0, count($arr)+1, array()); 
    $combinations[0] = array(''); 
    for ($i = 0, $n = count($arr); $i < $n; ++$i) { 
     for ($l = $n-$i; $l > 0; --$l) { 
      $combinations[$l][] = implode('', array_slice($arr, $i, $l)); 
     } 
    } 
    return $combinations; 
} 

Voici un exemple:

$arr = array('d', 'f', 'w', 's'); 
var_dump(combinations($arr)); 

Ce produit le tableau suivant:

array(
    array(''),     // length=0 
    array('d', 'f', 'w', 's'), // length=1 
    array('df', 'fw', 'ws'), // length=2 
    array('dfw', 'fws'),  // length=3 
    array('dfws')    // length=4 
) 

Une brève explication:

For each i with 0 ≤ i < n, get all sub-arrays arr‍[i,‍i+‍l] with each possible length of 0 < ln - i.

+0

Ouais, cette réponse dont j'ai réellement besoin. Je vais essayer de comprendre le code ... Merci. –

+0

@hey: Je vais ajouter quelques explications. – Gumbo

20

Un algorithme est ici,

function getCombinations($base,$n){ 

$baselen = count($base); 
if($baselen == 0){ 
    return; 
} 
    if($n == 1){ 
     $return = array(); 
     foreach($base as $b){ 
      $return[] = array($b); 
     } 
     return $return; 
    }else{ 
     //get one level lower combinations 
     $oneLevelLower = getCombinations($base,$n-1); 

     //for every one level lower combinations add one element to them that the last element of a combination is preceeded by the element which follows it in base array if there is none, does not add 
     $newCombs = array(); 

     foreach($oneLevelLower as $oll){ 

      $lastEl = $oll[$n-2]; 
      $found = false; 
      foreach($base as $key => $b){ 
       if($b == $lastEl){ 
        $found = true; 
        continue; 
        //last element found 

       } 
       if($found == true){ 
         //add to combinations with last element 
         if($key < $baselen){ 

          $tmp = $oll; 
          $newCombination = array_slice($tmp,0); 
          $newCombination[]=$b; 
          $newCombs[] = array_slice($newCombination,0); 
         } 

       } 
      } 

     } 

    } 

    return $newCombs; 


} 

Je sais que ce n'efficent en aucune façon, mais en utilisant dans les petits ensembles ne devrait pas être un problème

premier paramètre de base est un tableau contenant éléments à prendre en compte lors de la génération de combinaisons.

pour une utilisation simple et sortie:

var_dump(getCombinations(array("a","b","c","d"),2)); 

et la sortie est

array 
    0 => 
    array 
     0 => string 'a' (length=1) 
     1 => string 'b' (length=1) 
    1 => 
    array 
     0 => string 'a' (length=1) 
     1 => string 'c' (length=1) 
    2 => 
    array 
     0 => string 'a' (length=1) 
     1 => string 'd' (length=1) 
    3 => 
    array 
     0 => string 'b' (length=1) 
     1 => string 'c' (length=1) 
    4 => 
    array 
     0 => string 'b' (length=1) 
     1 => string 'd' (length=1) 
    5 => 
    array 
     0 => string 'c' (length=1) 
     1 => string 'd' (length=1) 

Pour répertorier tous les sous-ensembles d'un tableau, en utilisant cet algorithme combinaisons il suffit d'exécuter

$base =array("a","b","c","d"); 

for($i = 1; $i<=4 ;$i++){ 
    $comb = getCombinations($base,$i); 

    foreach($comb as $c){ 
     echo implode(",",$c)."<br />"; 
    } 

} 

et sortie est

a 
b 
c 
d 
a,b 
a,c 
a,d 
b,c 
b,d 
c,d 
a,b,c 
a,b,d 
a,c,d 
b,c,d 
a,b,c,d 
+0

Wow, merci beaucoup; fonctionne très bien! – Kayvar

+0

Dans une liste comme Tableau ( [0] => 10 [1] => 10 [2] => 14 [3] => 39 [4] => 39 [5] = > 39 [6] => 39 [7] => 40 [8] => 40 [9] => 42 [10] => 42 [11] => 45 ) Comment puis-je créer des permutations comme 10, 10, 14 et pas seulement 10, 14, 39? – Kayvar

0

Voici ma fonction d'imprimer toutes les combinaisons de caractères possibles:

function printCombinations($var, $begin = 0, $preText = "") { 
    for($i = $begin; $i < count($var); $i++) { 
     echo $preText . $var[$i] . "\n"; 
     if(($i+1) < count($var)) 
      printCombinations($var, $i+1, $preText . $var[$i]); 
    } 
} 

printCombinations(array('a','b','c','d','e')); 
Questions connexes