【问题标题】:Recursion inside for loop confuses mefor循环内的递归让我感到困惑
【发布时间】:2021-07-14 14:14:51
【问题描述】:

我正在尝试获得这种模式:

[
  [,,2],
  [,2,1],
  [2,1,0]
]

我尝试了以下代码:

let n = 3
let mainArr = Array(n)
for (let i = 0; i < mainArr.length; i++) {
  mainArr[i] = new Array(n)
}
let odi = 0; // stands for one dimensional index
let tdi = n - 1; // stands for two dimensional index
let diagonalValue = n - 1;
for (let i = 0; i < n; i++) {
  recur(odi, tdi)
  odi++;
  tdi--;
  diagonalValue--;
}

function recur(frst, scnd) {
  if (mainArr[frst] === undefined || mainArr[scnd] === undefined) {
    return
  } else {
    mainArr[frst][scnd] = diagonalValue;
    return recur(frst + 1, scnd - 1)
  }
}

console.log(mainArr);

但我得到了这个输出:

[
  [,,2],
  [,1,],
  [0,,]
]

所以我认为在 for 循环中使用递归时我遗漏了一些关于递归的内容,因为我使用递归解决了许多问题,但只是以随意的方式而不在 for 循环中使用它。

您能否向我解释一下当我们在for 循环中使用递归函数时会发生什么。它是在每次迭代时调用自身,还是 for 循环等待递归函数完成,然后循环移动到下一次迭代?

【问题讨论】:

  • 至于你的最后一个问题:你可以用调试器分析自己。单步执行代码并检查变量。

标签: javascript for-loop recursion


【解决方案1】:

你可以使用一个函数来保存最后插入的数组。

function fill(n, array = Array(n + 1)) {
    array = array.slice(1);
    array.push(n);
    return [array, ...(n ? fill(n - 1, array) : [])]
}

console.log(fill(2));

【讨论】:

    【解决方案2】:

    您的尝试存在一些问题:

    recur 中,您使用scnd 作为外部维度的索引。那是该索引的错误维度。您应该将if 条件从:

     if (mainArr[frst] === undefined || mainArr[scnd] === undefined) {
    

    到这里:

     if (mainArr[frst] === undefined || scnd < 0) {
    

    在主程序中,您可能想调用recur 来填充矩阵的对角线,但tdi 值不应在迭代之间改变:每条对角线都从同一列开始。

    所以这是您的代码,需要进行最少的修正:

    let n = 3
    let mainArr = Array(n)
    for (let i = 0; i < mainArr.length; i++) {
      mainArr[i] = new Array(n)
    }
    let odi = 0; // stands for one dimensional index
    let tdi = n - 1; // stands for two dimensional index
    let diagonalValue = n - 1;
    for (let i = 0; i < n; i++) {
      recur(odi, tdi)
      odi++;
      diagonalValue--;
    }
    
    function recur(frst, scnd) {
      if (mainArr[frst] === undefined || scnd < 0) {
        return
      } else {
        mainArr[frst][scnd] = diagonalValue;
        return recur(frst + 1, scnd - 1)
      }
    }
    
    console.log(mainArr);

    当然,还有其他方法可以产生这种结果,通常更短。这里的递归可以很容易地转换为只是迭代,所以我不会在这里寻求递归解决方案。

    例如:

    let n = 3;
    let mainArr = [];
    for (let row = 0; row < n; row++) {
        mainArr[row] = [];
        for (let i = 0; i <= row; i++) {
            mainArr[row][n - 1 - row + i] = n - 1 - i;
        }
    }
    
    console.log(mainArr);

    【讨论】:

      猜你喜欢
      • 2015-09-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-13
      • 2017-05-03
      • 2020-12-11
      • 1970-01-01
      • 2018-10-03
      相关资源
      最近更新 更多