递归javascript函数不起作用

时间:2016-12-09 04:14:54

标签: javascript recursion

我正在尝试递归。

我只希望输出是输入乘以2的结果:output = 2*input

应该是这样,为什么它不起作用?

function fE(f) {
  if(f < 0){
    return 1;}
  else{
  return f + fE(f);}


}

console.log(fE(3)); // output 6
console.log(fE(6)); // 12

3 个答案:

答案 0 :(得分:3)

递归涉及一个基本案例,在您的情况下是一个零输入。那种情况下的答案是零。否则,将问题减少到两个的总和,并用一个参数减去一个递归调用函数的结果。如果输入为负,则返回否定输入的结果。

function fE(f) {
  if (f === 0) return 0;
  else if (f < 0) return -fE(-f);
  else return 2 + fE(f - 1);
}

console.log(fE(3)); // output 6
console.log(fE(6)); // 12
console.log(fE(-4)); // -8

您的代码:

function fE(f) {
  if(f < 0){
    return 1;}
  else{
  return f + fE(f);}
}

有以下问题:

  1. 如果输入为零或更少,您可能希望返回零,而不是一个。
  2. 否则,您希望使用小于输入的值递归。 fE(f)会导致无限循环,对吗?
  3. 您不希望将f添加到递归结果中;你想加2,这是你获得倍增效果的地方。

答案 1 :(得分:1)

您显示的函数将尝试无限递归,因为f + fE(f)行上的递归调用每次都会传递相同的f值,这意味着if测试第一行总是失败。

以递归方式实现此方法没有任何意义,因为您可以使用一行代码计算正确的结果:

function fE(f) { return 2 * f; }

也许一个更好的递归函数示例(用于学习目的)将是一个函数,通过大量的递归调用将任意两个数字相乘:

multiply(10, 3)  // return 30

......再一次可以很容易地在一行中实现:

function multiply(a, b) { return a * b; }

...但你可以用这样的递归来做到这一点:

function multiply(a, b) {
  console.log(a, b);
  if (b === 0)
    return 0;
  else if (b === 1)
    return a;
  else if (b < 0)
    return -multiply(a, -b);
  else
    return a + multiply(a, b-1);
}

multiply(12, 4)  // 48
multiply(5, -3)  // -15
multiply(3, 0)   // 0

请注意,每次函数调用自身时,它会在第二个参数中传递不同的值,这样最终else if (b === 1)条件将为true,递归将停止。我已经包含了一个console.log(a,b),以便您可以自己查看每个调用的参数。

答案 2 :(得分:1)

@torazaburo和@nnnnnn给出了很好的答案 - 它们很实用,可以解决你眼前的问题。我会提供一些其他的选择,希望这些可以帮助你的大脑以各种方式思考递归程序。

另一种常见的递归技术是在辅助函数中使用状态变量

function mult (x, y) {
  function aux (result, counter) {
    if (counter === 0)
      return result
    else
      return aux (result + x, counter - 1)
  }
  return aux (0, y)
}

console.log(mult (5, 4)) // 20

这是另一种使用延续传递方式的技术

function multk (x, y, k) {
  if (y === 0)
    k (0)
  else
    multk (x, y - 1, function (result) { k (result + x) })
}

multk (5, 4, function (result) { console.log(result) /* 20 */ })

这是一个疯狂的简化版本,只使用原始+1和原始-1。它可能看起来很复杂,但我为你构建它,以便你可以看到更复杂的递归过程是如何用较小的构建的。如果您可以遵循此代码,它可以帮助您更好地理解递归。

(我添加了一些console.log行,以便您可以更好地了解正在发生的事情。您不希望将这些行留在代码中。)

function add1 (x) {
  return x + 1
}

function sub1 (x) {
  return x - 1
}

function add (x, y) {
  console.log('adding:', x, y)
  if (y === 0)
    return x
  else
    return add (add1(x), sub1(y))
}

function mult (x, y) {
  function aux (result, counter) {
    console.log('multiplying:', result, counter)
    if (counter === 0)
      return result
    else
      return aux (add(result, x), sub1(counter))
  }
  return aux (0, y)
}

console.log('result:', mult (5, 4)) // 20

使用无限延续的同样的事情

function add1 (x, k) {
  k (x + 1)
}

function sub1 (x, k) {
  k (x - 1)
}

function addk (x, y, k) {
  console.log('adding:', x, y)
  if (y === 0)
    k (x)
  else
    add1 (x, function (x1) {
      sub1 (y, function (y1) {
        addk (x1, y1, k)
      })
    })
}

function multk (x, y, k) {
  function aux (result, counter, k) {
    console.log('multiplying:', result, counter)
    if (counter === 0)
      k (result)
    else
      addk (result, x, function (result1) {
        sub1 (counter, function (counter1) {
          aux (result1, counter1, k)
        })
      })
  }
  aux (0, y, k)
}

multk (5, 4, function (result) { console.log('result:', result) /* 20 */ })