在PHP中获取数组的所有排列
您可以通过两种方式找出数组的所有不同排列。
第一种是使用递归算法。这将数组缩小了一点,然后又将其重新粘贴在一起,最终导致了所有可用的不同排列。
$list = array(); function recursive_permutations($items,$perms = array( )) { static $list; if (empty($items)) { $list[] = join(',', $perms); } else { for ($i = count($items)-1;$i>=0;--$i) { $newitems = $items; $newperms = $perms; list($foo) = array_splice($newitems, $i, 1); array_unshift($newperms, $foo); recursive_permutations($newitems, $newperms); }; return $list; }; } $perms = recursive_permutations(range(1,3)); echo '' . print_r($perms, true) . '';
替代方法是使用强制方法,该方法只对数组进行随机组合,然后将生成的数组模式转换为字符串。这些字符串然后用作另一个数组的键。经过足够的迭代后,外部数组应包含所有可能的排列。这绝不是优雅或不错的方法,但是它在较小的数组上可以很好地工作。
function permutations($array) { $list = array(); for ($i=0; $i<=10000; $i++) { shuffle($array); $tmp = implode(',',$array); if (isset($list[$tmp])) { $list[$tmp]++; } else { $list[$tmp] = 1; } } ksort($list); $list = array_keys($list); return $list; } $perms = permutations(range(1, 3)); echo '' . print_r($perms, true) . '';
更新18/05/2011:
回看这段代码,我发现它有点密集,因为即使找到了所有排列,它也将始终运行该数组10,000次。为了防止它始终运行循环的整个10,000次迭代,可以通过计算数组长度的阶乘来查找将找到多少个排列。一旦达到此限制,我们就可以停止阵列。
function permutations($array) { $list = array(); $array_count = count($array); $number_of_permutations = 1; if ($array_count > 1) { for ($i = 1; $i <= $array_count; $i++) { $number_of_permutations *= $i; echo $number_of_permutations . ' ' . $i . "\n"; } } for ($i=0; count($list) < $number_of_permutations; $i++) { shuffle($array); $tmp = implode(',', $array); if (!isset($list[$tmp])) { $list[$tmp] = 1; } } ksort($list); $list = array_keys($list); return $list; }