PHP:如何获取无重复的无序元素组合?现有排列函数不符需求
搞定数组的无重复两两组合问题
嘿,你这明显是把**排列(Permutation)和组合(Combination)**搞混啦!你想要的是不考虑元素顺序的无重复组合(比如a,b和b,a算同一个结果),但你现在用的是排列函数,它会把所有顺序不同的情况都列出来,所以才会得到6种结果。
先理清楚核心区别:
- 排列:讲究顺序,
[A,B]和[B,A]是两个独立结果,3选2的话总共有3×2=6种 - 组合:不讲究顺序,
[A,B]和[B,A]算同一个,3选2的话总共有3种(就是你要的结果)
为什么你的当前代码不对?
你贴的permutations函数是生成排列的,它的逻辑就是遍历所有可能的元素顺序排列,所以返回6种结果完全符合它的设计,但这不是你需要的。
给你写个PHP的组合实现
下面这个函数专门生成无重复的组合,正好匹配你的需求:
function combinations($pool, $r) { $n = count($pool); // 边界情况处理:选的数量超过数组长度,或者选0个/负数个,直接返回空数组 if ($r > $n || $r <= 0) { return []; } // 选全部元素,直接返回原数组的包装 if ($r == $n) { return [$pool]; } // 选1个元素,直接把每个元素单独包装成数组返回 if ($r == 1) { return array_map(fn($item) => [$item], $pool); } $combinations = []; // 递归逻辑:要么包含第一个元素,和剩下元素的r-1组合合并 $firstItem = $pool[0]; $remainingItems = array_slice($pool, 1); foreach (combinations($remainingItems, $r - 1) as $subComb) { array_unshift($subComb, $firstItem); $combinations[] = $subComb; } // 要么不包含第一个元素,直接取剩下元素的r组合 $combinations = array_merge($combinations, combinations($remainingItems, $r)); return $combinations; } // 测试你的例子 $testPool = ['A', 'B', 'C']; $results = combinations($testPool, 2); print_r($results);
运行这段代码后,你会得到正好3种结果:
Array ( [0] => Array ( [0] => A [1] => B ) [1] => Array ( [0] => A [1] => C ) [2] => Array ( [0] => B [1] => C ) )
简单说下这个函数的逻辑
用递归的思路拆解问题:
- 要么把第一个元素放进组合里,然后从剩下的元素里选
r-1个和它搭配 - 要么不选第一个元素,直接从剩下的元素里选
r个 - 把这两种情况的结果合并,就得到了所有不重复的组合啦
这样就完全满足你的需求了!
内容的提问来源于stack exchange,提问作者Dave Hamilton
相关产品推荐
相关产品推荐

