递归方法不会在 return 上终止执行

Recursive method does not terminate execution on return

美好的一天。 我有一个递归方法的问题,这个方法将在 window 中打印一个数字。 给定数字 n 的函数,按照模式打印,例如:

n=16,差=5

16 11 6 1 -4 1 6 11 16

n=10,差=5

10 5 0 5 10

代码:

function pattern(number, dif, m = 0, nI = 0) {
  if (m === 2) {
    return 0;
  }
  var nI = nI !== 0 ? nI : number;
  if (!(m === 2)) {
    document.write(number + ' ')
  }

  if (number === 0 || number < 0) {
    pattern(number + dif, dif, 1, nI)
  }
  if (m === 0) {
    pattern(number - dif, dif, 0, nI)
  }
  if (m === 1) {
    if (nI == number) {
      pattern(false, false, 2, false)
    }
    pattern(number + dif, dif, 1, nI)
  }
}

pattern(10, 5)

基本上当数字在'n'时再次调用参数m = 2的函数,执行reurn但它进入总和:

if (m===1) {
  if (nI == number) {
    pattern(false, false, 2,false)
  }
  >>> pattern(number+dif, dif, 1,nI) <<<<
}

您对 pattern 的所有递归调用都需要与 return 一起使用。否则它会继续深入。

function pattern(number,dif,m=0, nI=0) {
    if (m===2) {
        return 0;
    }
    var nI = nI !== 0 ? nI : number;
    if (!(m===2)) {
        document.write(number+' ')
    }

    if (number=== 0 || number < 0){
        return pattern(number+dif, dif, 1,nI)
    }
    if (m===0) {
        return pattern(number-dif, dif, 0,nI)
    }
    if (m===1) {
        if (nI == number) {
            return pattern(false, false, 2,false)
        }
        return pattern(number+dif, dif, 1,nI)
    }
}

pattern(10,5)

您的代码可以稍微简化一下。每当您调用函数 foo() 时,函数体就会运行,一旦调用函数 returns/completes,代码就会从 foo() 函数调用之后的行继续执行。考虑到这一点,可以通过在 number 为正时递归调用 pattern() 来简化递归函数,然后 returning (完成递归函数)将代码执行传递回原始 pattern() 调用后的代码:

function pattern(number,dif) {
  if(number <= 0) {
    document.write(number);
  } else {
    // If number > 0
    document.write(number + ' ');
    pattern(number-dif, dif);
    document.write(' ' + number);
  }
}

pattern(16, 5);

想法如下:当你遇到一个正数 non-zero 时打印它,然后再次调用 pattern,然后打印给定的数字,然后再次调用 pattern 等等,直到最后,您到达了 negative/zero 个号码。当发生这种情况时,您不再需要进行任何递归调用(请参阅上面的 if-block),因此我们 return 到我们模式函数的原始调用者,这是之前的递归调用。在我们将控制权交还给调用函数之后,我们可以再次打印当前数字:

pattern() --> 16
|  pattern() --> 11
|  |  pattern() --> 6
|  |  |  pattern() --> 1
|  |  |  |  pattern() --> -4 (returns to above function, printing 1 again)
|  |  |  pattern() --> 1
|  |  pattern() --> 6
|  pattern() --> 11
pattern() --> 16

在我看来,创建一个实用函数来将值累积到一个数组中,然后加入并记录它们(而不是让函数执行记录)更清晰:

function pattern(number, dif) {
  return number <= 0 
    ? [number]
    : [number, ...pattern(number-dif, dif), number];
}

const patternArr = pattern(16, 5);
document.body.textContent = patternArr.join(' ');