繁体   English   中英

递归javascript函数不起作用

[英]Recursive javascript function is not working

我正在尝试递归。

我只希望输出是输入乘以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

递归涉及一个基本情况,在您的情况下为零输入。 在这种情况下,答案为零。 否则,将问题减少为2的总和,并以较少的参数递归调用函数的结果。 如果输入为负,则返回输入求反结果的求反。

 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,这是获得双倍效果的地方。

如图所示,您的函数将尝试无限递归,因为具有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)以便您可以自己查看每个调用的参数。

@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 */ }) 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM