
本文提供一个高效、可扩展的php函数,用于生成数组中所有长度不小于2的全排列(即排除单元素子集),支持任意长度输入数组,并返回结构清晰的二维数组结果。
本文提供一个高效、可扩展的php函数,用于生成数组中所有长度不小于2的全排列(即排除单元素子集),支持任意长度输入数组,并返回结构清晰的二维数组结果。
在实际开发中,我们常需对一组元素生成所有可能的有序组合,但标准全排列(如 n!)通常包含单元素序列和完整长度排列,而业务场景(如推荐组合、路径枚举、测试用例生成)往往要求排除长度为1的排列,仅保留长度 ≥ 2 的所有非空真排列——即所有 k-permutations,其中 k ∈ [2, n]。
下面是一个经过优化的递归实现,它:
- ✅ 自动跳过长度为1的中间结果;
- ✅ 每次拼接后立即存入结果集(避免冗余判断);
- ✅ 返回标准 PHP 索引数组(每个子数组为纯字符串序列);
- ✅ 兼容 PHP 7.4+,无依赖,开箱即用。
function perm(array $arr, string $temp = '', array &$result = []): array {
$n = count($arr);
// 终止条件:无剩余元素可选
if ($n === 0) {
return $result;
}
for ($i = 0; $i = 1) {
$result[] = explode(' ', $newTemp);
}
// 递归处理剩余元素(排除已选元素)
$remaining = array_merge(array_slice($arr, 0, $i), array_slice($arr, $i + 1));
perm($remaining, $newTemp, $result);
}
return $result;
}
// 使用示例
$allPerms = perm(['one', 'two', 'tree']);
print_r($allPerms);
输出说明:
该函数对 ['one','two','tree'] 输出共 12 个子数组(6 个长度为2的排列 + 6 个长度为3的全排列),完全匹配需求示例,且顺序更可控(按递归深度与字典序混合生成)。
注意事项:
- 时间复杂度为
O(∑ₖ₌₂ⁿ P(n,k)) = O(n! × e),属指数级;对n > 9的输入请谨慎使用,建议配合内存限制或分批处理; - 若需去重(如输入含重复值),应在递归前对
$arr调用array_unique()并array_values()重索引; - 如需按长度分组(如先输出所有二元组),可后期用
array_group_by($result, 'count')处理; - 本实现不修改原始数组,全程使用值传递与切片,线程安全。
总结:该方案以清晰逻辑替代原代码中易错的 empty($temp) 判断,通过 substr_count(' ') ≥ 1 精确控制最小长度门槛,兼顾可读性与实用性,是生成「非平凡排列」(non-trivial permutations)的推荐实践。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











