简体   繁体   English

递归javascript函数不起作用

[英]Recursive javascript function is not working

I'm trying recursion. 我正在尝试递归。

I just want the output to be the result of multiplying the input by 2: output = 2*input . 我只希望输出是输入乘以2的结果: output = 2*input

It should be like this, why is it not working? 应该是这样,为什么不起作用?

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


}

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

Recursion involves a base case, which in your case is an input of zero. 递归涉及一个基本情况,在您的情况下为零输入。 The answer in that case is zero. 在这种情况下,答案为零。 Otherwise, reduce the problem to the sum of two and the result of calling the function recursively with an argument one less. 否则,将问题减少为2的总和,并以较少的参数递归调用函数的结果。 If the input is negative, return the negation of the result of the negation of the input. 如果输入为负,则返回输入求反结果的求反。

 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 

Your code: 您的代码:

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

has the following problems: 有以下问题:

  1. If the input is zero or less, you probably want to return zero, not one. 如果输入为零或更少,则可能要返回零,而不是一。
  2. Otherwise, you want to recurse with a value of one less than the input. 否则,您希望递归的值比输入小一。 fE(f) will cause an infinite loop, right? fE(f)将导致无限循环,对不对?
  3. You don't want to add f to the result of recursing; 您不想将f添加到递归结果中; you want to add 2, which is where you get the doubling effect. 您想添加2,这是获得双倍效果的地方。

Your function as shown will try to recurse infinitely, because the recursive call on the line with f + fE(f) passes the same value of f through each time, which means the if test on the first line will always fail. 如图所示,您的函数将尝试无限递归,因为具有f + fE(f)的行上的递归调用每次都传递相同的f值,这意味着第一行的if测试将始终失败。

It doesn't make any sense to implement this recursively, because you can calculate the correct result with one line of code: 递归地实现它没有任何意义,因为您可以用一行代码来计算正确的结果:

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

Perhaps a better example of a recursive function (for learning purposes) would be a function that multiples any two numbers together via a larger number of recursive calls: 递归函数的一个更好的例子(出于学习目的)可能是通过大量递归调用将任意两个数相乘的函数:

multiply(10, 3)  // return 30

...again that could easily be implemented in one line: ...同样可以轻松地在一行中实现:

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

...but you could do it with recursion like this: ...但是您可以像这样递归地做到这一点:

 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 

Notice that each time the function calls itself it passes a different value in the second argument, so that eventually the else if (b === 1) condition will be true and the recursion will stop. 请注意,每次函数调用自身时,它都会在第二个参数中传递一个不同的值,以便最终else if (b === 1)条件为true,并且递归将停止。 I've included a console.log(a,b) so that you can see for yourself what the arguments are on each call. 我包含了console.log(a,b)以便您可以自己查看每个调用的参数。

Great answers from @torazaburo and @nnnnnn – they're practical and should solve your immediate problem. @torazaburo和@nnnnnn的很好答案–它们很实用,应该可以解决您的直接问题。 I'll offer some other alternatives in hope that these will help your brain think about recursive procedures in a variety of ways. 我将提供其他替代方法,希望这些方法可以帮助您的大脑以多种方式思考递归过程。

Another common recursion technique is using state variables in an auxiliary function 另一种常见的递归技术是在辅助函数中使用状态变量

 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 

Here's another technique that uses continuation passing style 这是另一种使用延续传递样式的技术

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

And here's a nutty boiled down version that uses nothing more than primitive +1 and primitive -1 . 这是一个坚果式的简化版本,仅使用原始+1和原始-1 It may seem complicated but I constructed it for you so that you can see how more complex recursive procedures can be built out of smaller ones. 它看起来似乎很复杂,但是我为您构建了它,以便您可以了解如何用较小的递归程序构建更复杂的递归程序。 If you can follow this code, it should help you gain a greater understanding of recursion. 如果您可以遵循此代码,它将有助于您更好地理解递归。

(I added some console.log lines so you can get a better visualization of what's happening. You wouldn't want to leave these in your code.) (我添加了一些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 

And the same thing using undelimited continuations 和同样的事情使用无限分隔的延续

 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