JavaScript递归实现数组全组合:现有代码如何修改以正确输出?
问题描述
现有代码如下:
var Combination = []; function Reduce(List, Target) { if(List.length > 1) { return Reduce(List.filter(word => word !== List[0]), List[1]); } else { return List[0]; } }
需求:当输入数组X = ["AB", "DE", "SZ", "YY"]时,需返回所有可能的非空组合(例如["AB", "DE"]、["AB", "YY", "SZ"]等)。
尝试用递归实现,但卡在将结果存入Combination数组的环节,请问需要修改代码的哪些部分才能获取所有组合?若实现思路有误,也请帮忙指正。
解决方案
原思路的核心问题
原Reduce函数的逻辑完全偏离了生成所有组合的目标:它只是不断移除数组第一个元素,最后返回剩余的单个元素,没有任何组合生成的分支处理逻辑,根本无法实现需求。
递归生成所有组合的核心应该是对每个元素做「选」或「不选」的分支处理,通过回溯来覆盖所有可能的组合情况。
修改后的递归实现代码
var Combination = []; function generateAllCombinations(arr, currentCombo = []) { // 当前组合非空时,存入结果数组(存副本避免引用修改) if (currentCombo.length > 0) { Combination.push([...currentCombo]); } // 遍历剩余元素,逐个做选择分支 for (let i = 0; i < arr.length; i++) { // 选择当前元素加入组合 currentCombo.push(arr[i]); // 递归处理后续元素(从i+1开始避免生成重复顺序的组合) generateAllCombinations(arr.slice(i + 1), currentCombo); // 回溯:移除当前元素,处理「不选」的分支 currentCombo.pop(); } } // 调用示例 const X = ["AB", "DE", "SZ", "YY"]; generateAllCombinations(X); console.log(Combination);
代码关键说明
- 递归分支逻辑:
- 每次进入递归先存入当前非空组合,用
[...currentCombo]创建数组副本,避免后续修改currentCombo时影响已存入的结果。 - 遍历数组元素时,选择当前元素后递归处理剩余元素,递归返回后再移除当前元素(回溯),以此覆盖「选」与「不选」所有情况。
- 每次进入递归先存入当前非空组合,用
- 重复组合控制:
- 代码中用
arr.slice(i + 1)确保递归只处理当前元素之后的元素,避免生成["AB","DE"]和["DE","AB"]这类顺序不同的重复组合。如果需要包含这类顺序不同的组合,把arr.slice(i + 1)改成arr.slice(0,i).concat(arr.slice(i+1))即可。
- 代码中用
- 空组合支持:如果需求允许包含空组合,直接去掉
if (currentCombo.length > 0)的判断,递归开头直接存入当前组合即可。
内容的提问来源于stack exchange,提问作者Undefined
相关产品推荐
相关产品推荐

