Javascript 列出 1、2、3 相加等于 4 的所有方式,顺序很重要。例如,[1, 1, 1, 1] 是一种方式

tha*_*hao 7 javascript recursion

列出 1、2、3 加起来等于 4 的所有方式,顺序很重要。例如,[1, 1, 1, 1]是一种方式。[1,1,2]不同于[1,2,1]

我已经在纸上找到了一种工作方式。但我仍然无法为其编写代码。请帮忙,请查看这张我的想法的图片以确保清晰。

我写的这段代码失败了。但这就是我已经走了多远。

function theseAddToSum(steps = [], sum) {
  let results = [];

  if (steps.length < 1) return 'error'

  for (let i = 0; i < steps.length; i++) {
    let cur = steps[i];
    let remaining = sum - cur; 

    if (remaining >= 0) {
      console.log('sum', sum, 'step', cur)
      let c = theseAddToSum(steps, remaining)
    }
  }

  return results
}
console.log(theseAddToSum([1, 2, 3], 4))
Run Code Online (Sandbox Code Playgroud)

正如我一样console.log('sum', sum, 'step', cur),我得到了想要的结果:

sum 4 step 1
sum 3 step 1
sum 2 step 1
sum 1 step 1
sum 2 step 2
sum 3 step 2
sum 1 step 1
sum 3 step 3
sum 4 step 2
sum 2 step 1
sum 1 step 1
sum 2 step 2
sum 4 step 3
sum 1 step 1
Run Code Online (Sandbox Code Playgroud)

我的问题是我不知道如何将结果推送到results数组。它应该看起来像[[1,1,1,1], [1,1,2], [1,2,1], [1,3], [2,1,1], and on]

tri*_*cot 2

一些问题:

  • 尽管递归调用返回的数组被捕获在变量中c,但该变量没有进一步使用,因此它没有用。

  • results初始化为[],但随后永远不会修改/扩展,因此return result保证最终返回该空列表。

  • 上述两个问题需要通过迭代中存在的解决方案来解决c:将当前值附加到这些解决方案(因为我们已经减去该值以获得这些解决方案),并将这些扩展解决方案附加到当前数组results

  • remaining等于0时,进行更多的递归调用是没有意义的。这实际上是递归的基本情况。(我更喜欢在函数开始时在递归中进行更深入的检查:如果总和为 0,我们应该返回一个空解决方案,然后当我们退出递归时可以通过所选值对其进行扩展) 。

  • 不相关,但最好用分号分隔语句。您不会是第一个陷入自动分号插入陷阱的人。最好控制一下。

这是一个更正的版本:

function theseAddToSum(steps = [], sum) {
    // Base cases:
    if (sum < 0) return []; // No solutions
    if (sum == 0) return [[]]; // A solution

    let results = [];
    if (steps.length < 1) return 'error';

    for (let i = 0; i < steps.length; i++) {
        let cur = steps[i];
        let remaining = sum - cur; 
        let c = theseAddToSum(steps, remaining)
        // Use the solutions we got back from recursion
        for (let solution of c) {
            solution.push(cur); // ... then extend them
            results.push(solution); // ... and collect them
        }
    }        
    return results;
}

console.log(theseAddToSum([1, 2, 3], 4));
Run Code Online (Sandbox Code Playgroud)