2017-08-06 5 views
3

Ich habe zwei Versionen einer PHP 7-Funktion erstellt, die ein Array verwendet und eine Liste von Arrays zurückgibt, die alle Permutationen der ursprünglichen Array-Member anzeigen. Für die Eingabe [1,2,3] würde die erwartete Ausgabe alle sechs Permutationen von 1, 2 und 3 sein.PHP: Warum geben diese unterschiedliche Ergebnisse aus?

Ich erwartete beide Versionen der Funktion, um die gleiche Ausgabe zu geben, aber kann nicht herausfinden, warum sie nicht . Hier ist die erste (funktioniert wie erwartet):

function permutations(array $input): array { 
    $func = function (array $selected, array $chooseFrom, array &$results) 
      use (&$func) { 

    foreach ($chooseFrom as $k => $unchosen): 
     $selectedCopy = $selected; // make a copy 
     $chooseFromCopy = $chooseFrom; // make a copy 

     $selectedCopy[] = $unchosen; // add the next unchosen item to selected list 
     array_splice($chooseFromCopy, $k,1); // remove the item from chooseFrom list 
     $func($selectedCopy, $chooseFromCopy, $results); // recursive call 
    endforeach; 

    // If we've used all items. Add selection to results 
    if (empty($chooseFrom)) $results[] = $selected; 
    }; 

    $results = []; 
    $func([], $input, $results); 
    return $results; 
} 

Als ich permutations([1,2]) nennen bekomme ich das erwartete Ergebnis: [[1,2],[2,1]].

Hier ist die nicht funktionierende Version der Funktion. Der einzige Unterschied liegt in der foreach:

function permutations2(array $input): array { 

    $func = function (array $selected, array $chooseFrom, array &$results) 
      use (&$func) { 

    foreach ($chooseFrom as $k => $unchosen):  
     $chooseFromCopy = $chooseFrom; // make a copy 

     $selected[] = $unchosen; // add the next unchosen to the selected list 
     array_splice($chooseFromCopy, $k, 1); // remove the item from chooseFrom list 
     $func($selected, $chooseFromCopy, $results); // recursive call 
    endforeach; 

    // If we've used all items. Add selection to results 
    if (empty($chooseFrom)) $results[] = $selected; 
    }; 

    $results = []; 
    $func([], $input, $results); 
    return $results; 
} 

Als ich permutations2([1,2]) nenne ich ein schlechtes Ergebnis: [[1,2],[1,2,1]]

Warum gibt es einen Unterschied ??

+0

Das Problem ist über die Variable „$ selected“ hält die Ergebnisse der ersten Iteration der ersten Schleife für und es muss vor gelöscht werden in die nächste Iteration der Schleife gehen. Hinzufügen der Zeile "$ selected = array();" vor der endforeach-Anweisung wird der Code funktionieren. –

Antwort

2

Das Problem betrifft die Variable "$ selected", die die Ergebnisse der ersten Iteration der for-Schleife enthält und vor der nächsten Iteration der Schleife neu initialisiert werden muss. Speichern des "$ selected" in einer anderen Variablen (sagen wir $ tempselected) vor der for-Schleife und Reinitialisierung "$ selected" Variable mit $ tempselected vor endforeach Anweisung wird den Code arbeiten. Aber das ändert, ist fast die gleiche wie die Arbeitsprobe der Funktion :)

<?php 

function permutations2(array $input): array { 

    $func = function (array $selected, array $chooseFrom, array &$results) 
      use (&$func) { 
    $selectedTemp = $selected; 

    foreach ($chooseFrom as $k => $unchosen):  
     $chooseFromCopy = $chooseFrom; // make a copy 

     $selected[] = $unchosen; // add the next unchosen to the selected list 
     array_splice($chooseFromCopy, $k, 1); // remove the item from chooseFrom list 
     $func($selected, $chooseFromCopy, $results); // recursive call 
     $selected = $selectedTemp; 
    endforeach; 

    echo("<br>After For Loop <br>"); 
    // If we've used all items. Add selection to results 
     if (empty($chooseFrom)) { $results[] = $selected; } 
    }; 

    $results = []; 
    $func([], $input, $results); 
    return $results; 
} 
$res = permutations2(['a','b','c']); 
+0

Nur mit mehr Arten von Eingabewerten getestet - Das Löschen hilft auch nicht, wenn die Größe des Eingabe-Arrays größer als 2 ist. Es wird geprüft, ob es einen einfachen Weg gibt, dies anders als die erste Version der Funktion zu beheben. –

Verwandte Themen