递归(二)

上面的一篇文章已经简单说明了递归的一些使用,但是留下了一个问题,利用递归求斐波那契的第n项的时候,求到稍微大一点的数的时候,会出现求不出来的现象。

下面对这个现象进行验证
var i = 0;//声明一个变量,用来记录调用getN函数的次数
       function getN(n){
            i++;
           if( n == 1 || n == 2){
               return 1;
           };

           return getN(n-1)+getN(n-2);
       }
       console.log(getN(30),i);

在这里插入图片描述
电脑性能好的小伙伴可以试一下,当尝试求第50项的时候,会发现一直加载求不出来,之所以会出现这个原因是因为调用函数的次数太多了,调用函数是要消耗时间的。调用那么多次是因为求了很多重复的项。下面简单画了一个图,帮助理解一下。
在这里插入图片描述

解决方案

不要求那么多重复的项,把已经求过的项,用一个对象保存起来,后面如果还要求这个项就直接去这个对象中取出来。

var obj = {}; //这个obj对象是用来保存已经求过的项的值.
        var i = 0; //声明一个变量,用来记录调用getFB这个函数的次数
        function getN(n){
            i++;
            //我们先判断一下这个n位以前求过没有,如果求过就直接取值,如果没有求过就求. 
            if(obj[n] != undefined){
                //如果进到这里来,说明这个n项以前求过已经保存进了obj对象中了. 
                return obj[n];
            }else {
                //如果进到这里来,说明这个n项以前没有求过,那就要求咯. 
                if(n == 1 || n == 2){
                    obj[n] = 1; //把求出来的数给存起来. 
                    return 1;
                }else {
                    obj[n] = getN(n-1) + getN(n-2);//把求出来的数给存起来.
                    return obj[n];
                }
            }
        }
        console.log(getN(50),i);
        //42 267914296 81
        //50 12586269025 97
        //从i的取值我们可以看出我们已经大大提高了程序的执行效率

按照上面的这种写法,总感觉有些怪怪的,getN是一个独立的函数,但始终要和外面的obj对象取得关联才可以完成它的功能

解决方案使用闭包

function createN(){
        var obj = {}; //用来保存已经求过项的值
        function getN(n){
            if(obj[n] != undefined){
                return obj[n];
            }else{
                if(n == 1 || n == 2){
                    obj[n]=1;
                    return obj[n];
                }else{
                    obj[n] = getN(n-1) + getN(n-2);
                    return obj[n];
                }
            }
        }
        return getN;
    }
    console.log(createN()(50));

以上就是对使用递归求斐波那契第n项的一个程序优化。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

️不倒翁

你的鼓励就是我前进的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值