需求背景:计算出数组['A','B','C','D']各种排列组合,希望得到的是数据如下图
直接上代码:
private function finish_combination($array, &$groupResult = [], $splite = ',')
{
$result = [];
$finish_result = [];
$this->diffArrayItems($array, $result);
foreach ($result as $value) {
$items = $this->array_combination($value, $splite);
if (!isset($groupResult[count($value)])) $groupResult[count($value)] = [];
$groupResult[count($value)] = array_merge($groupResult[count($value)], $items);
$finish_result = array_merge($finish_result, $items);
}
return $finish_result;
}
// 不同数组的值进行排列组合例如:['A','B','C'],排列如何出所有的可能性
private function array_combination($arr, $splite = ',')
{
$len = count($arr);
if ($len == 1) {
return $arr;
}
$result = array();
for ($i = 0; $i < $len; $i++) {
$tmp_arr = $arr;
unset($tmp_arr[$i]);
$tmp_arr = array_values($tmp_arr);
$tmp_result = $this->array_combination($tmp_arr, $splite);
foreach ($tmp_result as $val) {
$val .= $splite . $arr[$i];
$result[] = $val;
}
}
return $result;
}
private function getCombinations($input, $length, $start = 0, $current = array(), &$result = array())
{
if (count($current) === $length) {
$result[] = $current;
return;
}
for ($i = $start; $i < count($input); $i++) {
$current[] = $input[$i];
$this->getCombinations($input, $length, $i + 1, $current, $result);
array_pop($current);
}
}
// 获取不同个数的数组例如['A'],['B'],['C'],['D'],['A''B'],['A''c']......['A', 'B', 'C', 'D']
private function diffArrayItems($input, &$result)
{
for ($i = 1; $i <= count($input); $i++) {
$this->getCombinations($input, $i, 0, array(), $result);
}
}
//直接调用
$result = $this->finish_combination(['A', 'B', 'C', 'D']);
var_dump($result);
// 排列组合了所有的数据后,一般情况下,我们都想着验证下个数是否正确,
例如:
取 1 个元素的排列组合数为 P(4, 1) = 4! / (4 - 1)! = 4! / 3! = 4
取 2 个元素的排列组合数为 P(4, 2) = 4! / (4 - 2)! = 4! / 2! = 12
取 3 个元素的排列组合数为 P(4, 3) = 4! / (4 - 3)! = 4! / 1! = 24
取 4 个元素的排列组合数为 P(4, 4) = 4! / (4 - 4)! = 4! / 0! = 24
下面就需要另外一个函数
//此方法需要开启GMP扩展
private function nP($n)
{
$sum = 0;
for ($i = 1; $i <= $n; $i++) {
$sum += gmp_fact($n) / gmp_fact($n - $i);
}
return intval($sum);
}
// 然后直接调用
echo $this->nP(count('A', 'B', 'C', 'D']));