【问题标题】:I don't understand this case of recursion我不明白这种递归情况
【发布时间】:2020-04-16 04:41:21
【问题描述】:

这是来自 FreeCodeCamp 上 exercice 的解决方案

function countdown(n) {
  if (n < 1) {
    return [];
  } else {
    const arr = countdown(n - 1);
    arr.unshift(n);
    return arr;
  }
}

我理解递归的概念。我知道函数倒计时将重复直到 n

【问题讨论】:

  • 在基本情况下,countdown 返回空数组文字 []。这将分配给arr
  • “我理解递归的概念。”不要粗鲁,但考虑到你所坚持的,我认为你很好地理解这个概念。提示:倒计时返回什么,尤其是在 if 块中

标签: javascript recursion


【解决方案1】:

让我们按照模式进行一个相对简单的调用。这里又是函数:

function countdown(n) {
  if (n < 1) {
    return [];
  } else {
    const arr = countdown(n - 1);
    arr.unshift(n);
    return arr;
  }
}

假设你打电话给countdown(2)

循环 1:

1a) n不小于1

1b) arr 被初始化并设置为 countdown(1)

循环 2:

2a) n不小于1

2b) arr 被初始化并设置为 countdown(0)

循环 3:

3a) n 小于 1

3b) 一个空数组返回到循环 2

arr 是 []

循环 2 续

2c) arr.unshift 将数字 2 添加到数组的开头。

arr 是 [2]

2d) arr 返回到循环 1

循环 1 续

1c) arr.unshift 将数字 1 添加到数组的开头。

数组是 [1,2]

1d) arr 返回到函数调用

所以如果你写let result = countdown(2)console.log(result),你会得到:[1,2]

让我烦恼的是,我不知道 const arr 何时或如何变为和 数组。

查看步骤 3b、2b 和 2c:

3b) an empty array is returned to loop 2

2b) an arr is initialized and set to countdown(0)

2c) arr.unshift adds the number 2 to the start of the array.

将一个空数组设置为const arr,然后将数字 2 添加到该数组中。

现在看看步骤 2d 和 1c:

2d) arr is returned to loop 1

1c) arr.unshift adds the number 1 to the start of the array.

该数组被设置为像这样 (const arr = [2]) 的 new 数组,并将数字 1 添加到该数组中。最后在 1d 中,该新数组返回给调用该函数的表达式。对于每个递归循环,你都有这样的东西:

const arr = something

new const arr = old const arr

【讨论】:

  • 感谢您详细说明循环。让它更清楚,但让我烦恼的一个细节是:arr 在第三个循环中是 [] 。我知道该函数最终会返回一个空数组,但我不知道为什么将这个空数组分配给 arr。
  • @xgreed 你看到我几分钟前的更新了吗?我稍微回顾了一下。
  • countdown(2) => const arr = countdown(1) => const arr = countdown(0) => return []。 countdown(0) 返回一个分配给 arr 的空数组,一旦“循环”结束,countdown(1) arr.unshift 将 1 添加到 arr 和.....
  • @xgreed 是的,完全正确
【解决方案2】:

让我烦恼的是,我不知道 const arr 何时或如何变为和 数组。

看到基本情况返回一个空数组了吗?这就是一切的开始,这要归功于一旦代码从递归调用返回,您就可以继续使用数组结构。

代码说明

Unshift 将在第零个索引处附加 LIFO,意思是

最后一个是 1,它将被添加到数组中,之后数组将在第零个索引处添加数字 2,在第二个索引处您将拥有数字 1,之后将在第零个添加数字 3索引,第二个索引将是数字 2,最后一个索引将包含数字 1。现在您看到了模式...

尝试在控制台之间登录

function countDown(n) {
  if (n < 1) {
    return [];
  } else {
    const countArray = countDown(n - 1);
    console.log(n)
    countArray.unshift(n);
    return countArray;
  }
}
console.log(countDown(5));

如果你更习惯 ES6+ 语法,则将第一个元素 n 添加到数组的第一个位置,然后对其余部分进行解构。

function countDown(n) {
  if (n < 1) {
    return [];
  } else {
    const countArray=[n,...countDown(n - 1)];
    return countArray;
  }
}
console.log(countDown(5));

最后,您可以使用三元运算符使其成为单行:

const countDown = (n) => n < 1 ? [] : [n, ...countDown(n - 1)];
console.log(countDown(5));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-28
    • 1970-01-01
    • 2023-03-29
    • 2022-06-14
    相关资源
    最近更新 更多