![](/img/trans.png)
[英]I need some help to understand this combination of methods (reduce, concat and map)
[英]Need some help to understand recursion
我想了解,递归是如何工作的。 我有了基本的想法,但细节仍不清楚。 这是javascript中的一个简单示例:
function sumTo(n){
if (n > 1){
return n + sumTo(n-1)
} else {
return n
}
}
sumTo(3);
它应该计算3中的所有数字,结果是6(1 + 2 + 3 = 6),但我不知道,它是如何工作的。
好的,我们从条件开始。 3> 1,所以我们返回n并再次调用该函数,但如果括号内部将会是什么?
它看起来像这样:
3 + sumTo(2)// 3 - 1 = 2
或者我们不对n做任何事情,等待下一个功能:
3 + sumTo(n - 1)// n将在稍后出现
有人告诉我,最后一个函数会返回1到上面的函数,但我不知道它会用1来做什么。
如果对最终的假人有一些循序渐进的解释,请分享。
我知道有很多类似的问题,但没有找到任何帮助。
UPD:看起来我终于找到了它是如何工作的,花了两天时间问我所有人。 我会尝试解释像我这样的终极假人。 那会很长,但我希望有同样麻烦的人能找到这篇文章,这将是有用的。
首先,我想展示另一个递归的例子,这更容易一些。 我在http://www.integralist.co.uk/posts/js-recursion.html找到它并将值从(1,10)更改为(2,3)。
function sum(x, y) {
if (y > 0) {
return sum(x + 1, y - 1);
} else {
return x;
}
}
sum(2, 3);
当我们启动函数时,我们检查if条件y> 0.Y是3,所以条件为真。 所以我们返回sum(x + 1,y - 1),即sum(2 + 1,3-1),i。 总和(3,2)。
现在我们需要计算总和(3,2)。 再次,我们转到开头并从条件y> 0开始.Y是2,因此条件为真。 所以我们返回sum(x + 1,y - 1),即sum(3 + 1,2 - 1),i。 总和(4,1)。
现在我们需要计算总和(4,1)。 再一次,我们检查条件y> 0.Y是1,条件为真。 我们返回sum(x + 1,y - 1),即sum(4 + 1,1-1),i。 总和(5,0)。
现在我们需要计算sum(5,0)。 我们检查条件y> 0并且它是假的。 根据函数中的if-else,我们返回x,即5,因此,sum(2,3)返回5。
现在让我们对sumTo()做同样的事情;
function sumTo(n){
if (n > 1){
return n + sumTo(n-1)
} else {
return n
}
}
sumTo(3);
从sumTo(3)开始。 检查n> 1条件:3> 1为真,所以我们返回n + sumTo(n - 1),即3 + sumTo(3 - 1),即3 + sumTo(2)。
继续,我们需要计算sumTo(2)。
为此,我们再次从检查n> 1条件启动函数:2> 1为真,所以我们返回n + sumTo(n - 1),即2 + sumTo(2 - 1),即2 + sumTo( 1)。
继续,我们需要计算sumTo(1)。
为此,我们再次启动该功能并检查n> 1条件。 1> 1是假的,因此,根据if-else,我们返回n,即1.因此,sumTo(1)得到1。
现在我们将sumTo(1)的结果传递给上面的函数sumTo(2),我们之前说过我们需要sumTo(1)继续。
SumTo(2)返回n + sumTo(n-1),即2 + sumTo(2 - 1),即2 + sumTo(1),即2 + 1.因此,sumTo(2)得到3。
现在我们将sumTo(2)的结果传递给上层函数sumTo(3),我们之前说过我们需要sumTo(2)继续。
SumTo(3)返回n + sumTo(n-1),即3 + sumTo(3 - 1),即3 + sumTo(2),即3 + 3.因此,sumTo(3)最终得到6.所以, sumTo(3)返回6。
我的错误在于我尝试插入3而不是n,而n则减少到1。
感谢所有回答此问题的人。
没错, sumTo(n)
等到sumTo(n-1)
完成。
所以, sumTo(3)
等sumTo(2)
,
sumTo(2)
等sumTo(1)
,
然后sumTo(1)
返回1
,
sumTo(2)
返回2 + 1
和sumTo(3)
返回3 + 2 + 1
你可以理解
sumTo(3);
returns => 3 + sumTo(2) // n is greater than 1
returns => 2 + sumTo(1)
returns => 1 // 1 as n is not greater than 1
展示作品:
sumTo(4) = (4 + 3) + (2 + 1) = 10 // 4 + sumTo(3). function called four times
sumTo(3) = (3 + 2) + 1 = 6 // 3 + sumTo(2). called three times
sumTo(2) = (2 + 1) = 3 // 2 + sumTo(1). called twice
sumTo(1) = (1) = 1 // called once
如果你从头开始而不是从头到尾想到它,你可能会更容易缠头。 像这样:
sumTo(1) = 1 + sumTo(0) = 1
sumTo(2) = 2 + sumTo(1) = 3
sumTo(3) = 3 + sumTo(2) = 6
sumTo(4) = 4 + sumTo(3) = 10
注意现在你可以继续添加到列表中,并且很容易计算前一个,因为你只是添加两个总和。
事件链如下:
sumTo(3)
3并调用sumTo(2)
,它也调用sumTo(1)
并返回3,总计为6。
那有意义吗? 如果有人有疑问,我很乐意详细说明或澄清。 要理解的一个重要问题是为什么要使用递归和何时使用递归。 关于这个主题的一个很好的讨论可以在这里找到: 何时使用递归?
递归的典型例子是斐波那契序列。 另一个很好的例子是遍历计算机上的文件目录,例如,如果要搜索包含其他文件夹的文件夹中的每个文件。 您还可以使用递归来计算指数。
考虑一个更简单的递归示例:
function multiplyBy10(i) {
if ( !i ) return 0;
return 10+multiplyBy10(i-1);
}
此函数将使用递归将数字乘以10。 掌握递归是否切实可行是很好的,因为有时候它会使你的事情变得更容易。 但是,最好保持简单,不要在任何可能的情况下混淆自己。 :)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.