一直不能读懂javascript中的递归函数,不清楚里面的层层调用是什么逻辑?每次碰到递归函数就会晕。
比如下面一个javascript组合排序的代码,里面就是递归实现:
var arr = ['A','B','C','D',"E","F","G"];
function show(arr,num){
var resultNum = 0;
var iNow = 1;
if(num==1){
return arr.length;
}
function change(arr,iNow){
for(var i=0;i
看了很多遍,都不知道它里面的实现逻辑是什么?也不知道怎么打断点分析代码,就是感觉反复调用,让人很晕,怎么办?
求javascript大神就拿上面这个例子帮忙分析下,代码逻辑怎么实现的?如果能读懂递归函数,后面再慢慢尝试写递归函数。
Eidt
谁能解释解释这个递归?
function f(m,n)
{
if(m==0)return n+1;
if(n==0)return f(m-1,1);
return f(m-1,f(m,n-1));
}
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
打开控制台 执行一下, 按F10 逐步执行.
某些人说调不出, 只能说头脑
逻辑性不够. 不能怪方法不行.首先接触到一个递归, 先看函数内部
做了什么, 看不懂, 调试一遍,看内部的不懂的函数或分支
做了什么.在不明白, 说明你的智商只如嘲讽一般.其次这个函数目的就是算
阶乘.!arr.length/!(arr.length - 5)叹号为阶乘用“反复调用”来描述递归并不准确,个人认为更准确的描述应该是“递进调用”——区别在于一个强调的是次数的增加,另一个强调的是层次的递进。
抛开调用栈的一套理论,想要快速读懂一段递归函数,最关键的是准确描述这个函数到底做了什么,具体来讲一个比较可行的方法是搞清楚这个函数的参数和返回 —— 这两点搞懂之后就可以吧函数中所有出现递归的地方替换掉,这样就得到一个普通的函数,分析起来也就简单很多。
另外强烈推荐配合算法流程图来理解递归,效果会更好。
要看懂递归你要知道他是如何迭代的,比如
n!,把4!记作fun(4),则5!就是5*fun(4)这个很容易理解,所以n!可以这样表示:另外一个递归算法的启蒙问题就是汉诺塔问题,题主可以认真看一下这个思想,实际上跟
n!是一样的。回到你的问题,当iNow和num相等的时候change(arr,iNow)实际上是不是arr.length* (arr.length - 1)?我们把他简写一下iNow == num时change(n,iNow) = n * (n - 1)。再看一下change整个函数,当iNow != num的时候change(n, iNow)实际上是调用了change(n - 1,iNow + 1)并且循环了n次,是不是可以记成change(n, iNow) = n * change(n - 1, iNow + 1)?所以把具体的问题展开就是这样的:其实学习代码最好就是在脑里运算一遍。递归其实,很简单,不满足条件就调用自己,可以拿纸自己模拟计算,一次就弄明白了。比如。
`function a(b){
if (b<2)return false;
b--;
a(b);
}`
昨天手机没有写完。如上面的代码 我们执行
a(3);那么3相当于函数内的b,判断b大于2,那么执行b减一,即b等于2,然后执行a(2),2相当于函数内的b,判断b,b等于2,则执行b减一,即b等于1,执行a(1),1相当于函数内的b,判断b小于2,那么返回false,最终a(3)返回false。
可以这样在脑子里计算一遍,这样才能理解
递归,我的理解就是一个循环的闭包,而闭包就是在内存中保留某个对象的状态(你也可以理解为复制),递归就是不断的复制更新自己,直到满足条件。正如你的例子所述,change方法就是一个闭包,当change(arr,iNow+1);被启动时,就形成了一个闭包,复制一次自身状态(对象,值),进入循环,!iNow == num条件下递归调用闭包,再次复制,更新,再进入循环,进入条件....直到满足iNow == num,结束循环,停止调用闭包,也就停止了递归
看别人的不如自己思考总结一个,只要自己想出来一次,以后的基本都会有思路。
问题: 有一个100个台阶的阶梯,一次可以选择上一个台阶,或者两个台阶,最后上到楼梯顶有几种走法?
你自己试着解答一下,