5

我无法弄清楚这个递归调用是如何工作的。在递归调用中使用 not 运算符以某种方式使该函数确定给定的参数是奇数还是偶数。当。。。的时候 '!' 被忽略 fn(2) 和 fn(5) 都返回 true。

这个例子取自JavaScript Allonge 免费电子书,到目前为止,这本书非常出色。

var fn = function even(n) {
  if (n === 0) {
    return true;
}
  else return !even(n - 1);
}

fn(2); //=> true

fn(5); //=> false
4

3 回答 3

7
  1. 如果n === 0结果是true.
  2. 如果n > 0它返回n - 1.
    如果n === 1它会返回!even(0),或者false
    如果n === 2它会返回!even(1), 或!!even(0), 或true.
    如果n === 3它将返回!even(2), 或!!even(1), 或!!!even(0), 或false.
    等等...

一般来说:

  • 如果n是偶数,则将结果反转偶数次,这意味着它将返回true
  • 如果n是奇数,则将结果反转奇数次,这意味着它将返回false
于 2013-11-10T21:06:40.873 回答
3

上面的函数递归地递归它自己的否定。基本情况是当提供的数字变为零并且每次函数调用它自己时,数字减一。结果,在基本情况下,我们有 n 个以 true 开头的递归否定(其中 n 是提供的数字)。对于奇数个否定作为起始值,你得到假作为结果,对于偶数你得到真。总之:

  1. 从给定的 n 开始
  2. n的递归约简
  3. 基本情况:n=0 返回真
  4. 返回值的递归否定(在基本情况下从 true 开始) 结果:
    • 对于奇数个否定,返回的值为false
    • 对于偶数个否定,返回值为

假设我们有示例 n=5
递归减少 n。每个级别的 n 值:
5
  4
    3
      2
        1
          0(基本情况)
每个级别的返回值:
          true(基本情况)
        !true
      !!true
    !!!true
  !!!!true
!!!!!true

于 2013-11-10T21:20:38.913 回答
0

您的代码的变体可能是:

function even(n) {
  if (n === 0)
    return true;
  else
    return odd(n - 1);
}
function odd(n) {
  if (n === 1)
    return true;
  else
    return even(n - 1);
}

我们知道所有从 0 开始的正数都在偶数和奇数之间交替。您的示例所做的是定义odd哪个!even是正确的,因为奇数/偶数是不相交的。在您使用的版本中!not需要作为延续来完成。这意味着每个实例都需要在递归调用返回后对答案做一些事情。

于 2013-11-10T22:14:34.257 回答