2017-08-06 128 views
3

我構建了兩個版本的PHP 7函數,它接受一個數組,並返回顯示原始數組成員的所有排列的數組列表。例如,對於輸入[1,2,3],期望的輸出將是1,2和3的全部六個排列。PHP:爲什麼這些輸出不同的結果?

我期望這兩個版本的函數給出相同的輸出,但是不知道爲什麼它們沒有。這是第一個(按預期工作):

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

當我打電話permutations([1,2])我得到預期的結果:[[1,2],[2,1]]

這是該函數的非工作版本。唯一的區別是在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; 
} 

當我打電話permutations2([1,2])我得到一個壞的結果:[[1,2],[1,2,1]]

爲什麼會出現差異?

+0

問題是關於變量「$ selected」包含第一個for循環的第一次迭代的結果,它需要在清空之前清除進入循環的下一次迭代。添加行「$ selected = array();」在endforeach語句之前將使代碼工作。 –

回答

2

問題是關於變量「$ selected」持有for循環的第一次迭代的結果,並且在進入下一次迭代循環之前需要重新初始化。在for循環之前將「$ selected」存儲在另一個變量中(比如說$ tempselected),並在endforeach語句之前用$ tempselected重新初始化「$ selected」變量將使代碼生效。但是這種變化幾乎與函數的工作示例相同:)

<?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

剛剛使用更多類型的輸入值進行測試 - 如果輸入數組大小超過2,清除功能也無濟於事。檢查是否有任何簡單的方法可以解決此問題,而不是第一個版本的功能。 –

相關問題