zoukankan      html  css  js  c++  java
  • 记一个经典的递归题

    所谓递归:就是函数调用函数本身

    在数学中,常常使用到阶乘,累加之类的,这就是经典的递归函数了

    例如:输入一个数,要计算这个数的阶乘

    首先来分析一下:要计算阶乘,首先我们要确定阶乘的输入数是多少,例如是 n;

    那么:计算公式是什么呢?

    假设值为 f(n) , 那么

    f(n) = 1*2*3*4*5*6*7*8*9*10*.....*n;

    这就难办了,要一直乘法,何时是个头呢?

    再分析一下:f(n) = f(n-1)*n  只要n>1,算法永远成立

    好了,那我们就开始来算吧,从后往前推,知道n=1 为止,这个计算就完成了

    我们不需要去考虑要写多少算式,因为这是计算机帮我们写,不需要关心这些;只管照着这个逻辑去做就行

     1     <script>
     2         function jiecheng(n) {
     3             if (n == 1) {
     4                 return 1;
     5             } else {
     6                 return jiecheng(n - 1) * n;
     7             }
     8         }
     9 
    10         var jieguo1 = jiecheng(5);
    11         var jieguo2 = jiecheng(8);
    12         console.log(jieguo1);
    13         console.log(jieguo2);
    14     </script>

    增加一个新函数,使用新函数调用,仍然没有问题

     1     <script>
     2         function jiecheng(n) {
     3             if (n == 1) {
     4                 return 1;
     5             } else {
     6                 return jiecheng(n - 1) * n;
     7             }
     8         }
     9 
    10         var jiecheng1 = jiecheng; // 创建一个新函数,继续调用,仍然没有问题
    11         var jieguo1 = jiecheng1(5);
    12         var jieguo2 = jiecheng1(8);
    13         console.log(jieguo1);
    14         console.log(jieguo2);
    15     </script>

    对旧函数进行清空,然后再调用;

        <script>
            function jiecheng(n) {
                if (n == 1) {
                    return 1;
                } else {
                    return jiecheng(n - 1) * n;
                }
            }
    
            var jiecheng1 = jiecheng; // 创建一个新函数,继续调用,仍然没有问题
            jiecheng = null;          // 改变原先函数的指向,则会出错
            var jieguo1 = jiecheng1(5);
            var jieguo2 = jiecheng1(8);
            console.log(jieguo1);
            console.log(jieguo2);
        </script>

    原因:在函数的内部,我们仍然使用原来函数的函数名,即原来的指针;但是现在指针指向null 了,所以报错

    解决这个问题,我们会用到另外一个指针函数:arguments.callee   , 表示指向当前运行函数的指针;即当前正在运行的函数为sum,那么它指向sum ;如果当前运行的函数是hehehe,那么它指向heheh,它是一个变化的指针

    修改之后,我们得到的代码如下:这样,即使改变了原先函数的指向,也不会出现错误了

     1     <script>
     2         function jiecheng(n) {
     3             if (n == 1) {
     4                 return 1;
     5             } else {
     6                 return arguments.callee(n - 1) * n;
     7             }
     8         }
     9 
    10         var jiecheng1 = jiecheng; // 创建一个新函数,继续调用,仍然没有问题
    11         jiecheng = null; // 改变原先函数的指向
    12         var jieguo1 = jiecheng1(5);
    13         var jieguo2 = jiecheng1(8);
    14         console.log(jieguo1);
    15         console.log(jieguo2);
    16     </script>

    但是,在严格模式下,js 不允许使用 arguments.callee ,我们再来看另外一种情况

     1    <script>
     2         var jiecheng = (function f1(n) {
     3             if (n == 1) {
     4                 return 1;
     5             } else {
     6                 return f1(n - 1) * n;
     7             }
     8         });
     9 
    10         var jiecheng1 = jiecheng; // 创建一个新函数,继续调用,仍然没有问题
    11         jiecheng = null; // 改变原先函数的指向
    12         var jieguo1 = jiecheng1(5);
    13         var jieguo2 = jiecheng1(8);
    14         console.log(jieguo1);
    15         console.log(jieguo2);
    16     </script>

    这里,使用命名表达式来完成,即使把 jiecheng() 赋值为null 了,也不影响命名表达式内部的指针,所以能够执行

  • 相关阅读:
    SQLServer2012数据库降级至SQLServer2008R2的方法
    男程序猿和女程序猿的网恋—相见(二)
    收藏关于AI的相关的文章
    JAVA提高九:集合体系
    JAVA提高八:动态代理技术
    JAVA提高七:类加载器
    JAVA提高六:泛型
    JAVA提高五:注解Annotation
    JAVA提高四:反射基本应用
    JAVA提高三:反射总结
  • 原文地址:https://www.cnblogs.com/huanying2015/p/8734096.html
Copyright © 2011-2022 走看看