2010-11-25 7 views
9

hier zu bekommen, ist mein Code, alle Möglichkeiten zu bekommen:Rekursion Php alle Möglichkeiten von Strings

$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>';  

Aber wenn ich mehr hinzufügen möchte, dann werde ich auf eine weitere Schleife hinzuzufügen. Also, wie kann ich das mit Rekursion machen? Ich versuche es, ich versuche es, aber ich kann es wirklich nicht tun. Bitte helfen Sie und post-Beispiel so einfach wie möglich.

Vielen Dank.

+0

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

Antwort

14

Hier ist ein einfaches algo. Iterieren 1 bis 2 count (array) -1. Bei jeder Iteration, wenn j-te Bit in einer Binärdarstellung des Schleifenzählers gleich 1 ist, umfasst j-te Element in einer Kombination.

Da PHP 2 count (array) als ganze Zahl berechnen muss, darf diese PHP_INT_MAX niemals überschreiten. Auf einer 64-Bit-PHP-Installation können Sie das Array nicht mehr als 62 Elemente hat, wie 2 Aufenthalte unter PHP_INT_MAX während 2 übersteigt.

EDIT: Dieser berechnet alle möglichen Kombinationen, nicht Permutationen (dh 'abc' = 'cba'). Dazu wird das ursprüngliche Array binär dargestellt und von 0 bis zur Binärdarstellung des vollständigen Arrays "aufwärts gezählt", wodurch effektiv eine Liste aller möglichen eindeutigen Kombinationen erstellt wird.

$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, es ist so kurz. Was bedeutet <

+1

Dies wird nicht alle Möglichkeiten testen .. zum Beispiel wenn nur für [a, b] wird es dies ausgeben: a b ab was ist mit "ba"? –

+3

"ba" ist gleich wie "ab" in Begriffen von Kombinationen oder Mengen. Was Sie suchen, ist Permutationen. –

0

Dies ist ein Standard Permutation Frage, schauen Sie in auf „php Permutationen“, wenn Sie alle Variationen des Strings müssen.

3

Hier ist sie:

<?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"; 
    } 

?> 

Ausgang:

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

Auch read this;

+0

verwendet eine Menge Speicher:/"PHP Fataler Fehler: Erlaubte Speichergröße von 134217728 Bytes erschöpft (versucht, 72 Bytes zuzuordnen) in ..." – Kayvar

1

Sie können dies tun:

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; 
} 

Hier ist ein Beispiel:

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

Daraus ergibt sich die folgende Reihe:

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 
) 

Eine kurze Erklärung:

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

+0

Ja, diese Antwort, die ich tatsächlich brauche. Will versuchen, den Code zu verstehen ... Danke. –

+0

@hey: Ich werde eine Erklärung hinzufügen. – Gumbo

20

Ein Algorithmus ist hier,

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; 


} 

Ich weiß es nicht in irgendeiner Weise efficent ist, aber in kleinen Mengen verwendet kein Problem

erste Basisparameter sein sollte, ist ein Array mit Elemente, die berücksichtigt werden müssen, wenn Kombinationen generiert werden.

für einfache Bedienung und Ausgabe:

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

und Ausgang ist

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) 

Um alle Teilmengen einer Array-Liste, diese Kombinationen Algorithmus nur

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

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

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

} 

Und Ausgang ausführen ist

+0

Wow, vielen Dank; funktioniert super! – Kayvar

+0

In einer Liste wie Array ( [0] => 10 [1] => 10 [2] => 14 [3] => 39 [4] => 39 [5] = > 39 [6] => 39 [7] => 40 [8] => 40 [9] => 42 [10] => 42 [11] => 45 ) Wie kann ich Permutationen wie 10, 10, 14 und nicht nurerstellen 10, 14, 39? – Kayvar

0

Hier ist meine Funktion alle möglichen Zeichenkombinationen drucken:

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'));