JavaScript数组组合递归函数正常,转换为生成器版本结果错误如何解决
错误原因
你的生成器版本和原正常递归函数的核心逻辑差异有两点:
- 原递归函数的三个边界条件判断都通过
return直接终止函数执行,匹配到任意边界条件就不会再执行后续的reduce逻辑;但生成器版本的三个边界判断仅执行了yield操作,没有终止函数运行,匹配边界条件后仍然会继续执行下方的for循环逻辑,产生大量多余结果。 - 原递归函数在
k > set.length || k <= 0时返回空数组,表示没有符合要求的组合;但生成器版本在该边界下yield [],会产出空数组组合,拼接后会得到长度不符合要求的结果。
修复方案
调整边界判断的逻辑,匹配到边界后直接终止函数执行即可,修复后的完整代码如下:
function* combinations(set, k) { // 边界1:无符合要求的组合,直接终止,不返回任何值 if (k > set.length || k <= 0) return // 边界2:取全部元素,返回当前集合后终止 if (k === set.length) { yield set return } // 边界3:取单个元素,返回所有单元素数组后终止 if (k === 1) { yield* set.map(x => [x]) return } // 正常递归逻辑 for (let i = 0; i < set.length; i++) { for (const next of combinations(set.slice(i + 1), k - 1)) { yield [set[i]].concat(next) } } }
修复后调用测试用例[...combinations([1,2,3,4], 3)],会得到预期结果[[1,2,3],[1,2,4],[1,3,4],[2,3,4]],数量和元素长度均符合要求。
内容的提问来源于stack exchange,提问作者roberto tomás
相关产品推荐
相关产品推荐

