JavaScript Fibonacci细分

前端之家收集整理的这篇文章主要介绍了JavaScript Fibonacci细分前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

我希望我在这里发布这个问题是好的,即使我也在其他网站上发布了这个问题.如果我没有遵循正确的协议,我道歉并请立即告诉我,以便我可以删除帖子并学习我的课程.

我已经成为一名前端开发人员已有一年多了.我去学校学习网络开发,在简单的JavaScript方面,我认为自己是一个有能力的编码器.
但是当谈到编写任何类型的Fibonacci函数时,我无法做到.就好像我的大脑中缺少一块可以理解如何处理这个简单数字序列的东西.
这是一段工作代码,我很确定我是从John Resig的书或在线的某个地方得到的:

fibonacci = (function () {
    var cache = {};
    return function (n) {

        var cached = cache[n];
        if (cached) return cached;

        if (n <= 1) return n;
        console.log(n);

        return (cache[n] = fibonacci(n - 2) + fibonacci(n - 1));
    };
}());

当我用10作为参数调用这个函数时,我得到了这个序列:10,8,6,4,2,3,5,7,9

这是我的理解:

fibonnaci被赋予一个立即调用函数表达式(或自动执行blah blah blah),使用传递的任何参数向其启动缓存.
如果争论已经存在于缓存中,我们就会将其归还,让我们的生活永远平静下来.
如果论证是1或更少,那也是功能的终结,永久的和平再次发生.
但如果这些条件都不存在,那么该函数会返回这个语句,让我感觉好像我只是一个穿着人类西装的猴子.

我想做的是以正确的顺序产生前10个斐波纳西数,因为如果我能做到这一点,那么我会觉得我至少理解它.

因此,当前两个条件失败时,代码会创建一个新的缓存变量并将其设置为等于fibonacci函数的结果,无论参数是否减去2,然后它将结果减去1 ….现在我的问题

>问题1:如果从未计算过fibonacci(n),函数如何知道fibonacci(n-2)是什么?
>问题2:递归函数是线性的,还是它们遵循的是什么顺序?
>问题3:如果我无法理解这一点,我是否有希望成为一名程序员?

感谢您的时间.

经过这个块之后,我稍微改变了一下这个函数,看看我是否可以保留变量中的结果并输出它,只是为了看看会发生什么,我得到了一些非常意想不到的结果.

这是改变:

fibonacci = (function () {
        var cache = {};
        return function (n) {

            var cached = cache[n];
            if (cached) {
                console.log(cached);
                return cached;
            }

            if (n <= 1) {
                console.log(n);
                return n;
            }
            console.log(n);

            var result = (cache[n] = fibonacci(n - 2) + fibonacci(n - 1));
            console.log(result);
            return result;
        };
    }());

这是结果模式:
    10,1,13,21,9,34,55
为什么会这样?

最佳答案
好吧,让我们从你理解的东西开始(或者说你理解):

fibonnaci is assigned an immediately invoked function expression (or self executing blah blah blah),to which a cache is initiated with whatever argument was passed.

不完全:斐波那契被指定了IIFE的返回值.有区别.在IIFE中,我们有一个return function(n)语句.正如其名称所暗示的那样,IIFE立即被引用.函数被创建,执行,一旦返回,就不会被任何地引用(显式).函数返回,分配给变量fibonacci.
这个IIFE确实创建了一个对象文字,称为缓存.这个对象存在于IIFE的范围内,但是because of JS’s scope scanning(这个答案链接到其他人……所有这些都解释了JS如何将名称解析为它们的值),这个对象仍然可以被返回的函数访问,现在被分配给斐波那契.

If the argument was already in the cache,we just return it and live our lives in everlasting peace. If the argument is 1 or less,that is also the end of the function,everlasting peace ensues once more. But […]

好吧,现在缓存不是在每个函数调用上反复创建的(IIFE只调用一次,这就是创建缓存的地方).如果返回的函数(fibonnaci)更改了它,则对该对象的更改将在内存中保留. Closure vars,就是可以使用缓存来保持函数调用之间的状态.你说的所有其他事情(n< = 1)都是标准的递归函数...它是阻止无限递归的条件.

But if neither of these conditions exist,then the function returns this statement that makes me feel as if I am just a monkey in a human suit.

嗯,这实际上是有趣的部分.这是真正的魔法发生的地方.
正如我已经解释的那样,fibonnaci没有引用IIFE,而是引用了返回函数

function(n)
{
    var cached = cache[n];
    if (cached)
    {
        return cached;
    }
    if (n <= 1)
    {
        return n;
    }
    return (cache[n] = (fibonacci(n-2) + fibonnaci(n-1)));
}

这意味着,每次出现的斐波那契都可以被功能体所取代.调用fibonnaci(10)时,最后一个(return)语句应该读作:

返回(cahce [n] = fibonacci(8)fibonnaci(9));

现在,正如你所见,斐波纳契(8)和斐波纳契(9)在回归值中被称为.这些表达式也可以完整写出:

return (cache[10] = (fibonnaci(6) + fibonacci(7)) + (fibonacci(7) + fibonacci(8)));
//which is,actually:
return (cache[10 = ( retrun (cache[6] = fibonacci(4) + fibonacci(5))
                   //since fibonacci(6) cached both fibonacci(5) & fibonacci(6)
                     + return (cache[7] = cache[5] + cache[6])
           + return cache[7] + return (cache[8] = cache[6] + cache[7]

这就是缓存功能实际上与…有关的方式……

我们可以重复这个,直到我们调用fibonnacci(1)或fibonacci(0),因为在那种情况下n< = 1,并且将返回而不再有任何递归调用.
还要注意的是,在完全写入fibonnaci(9)时,这实际上分解为斐波那契(7)斐波那契(8),这些调用之前都进行过,这就是为什么结果被缓存的原因.如果你不缓存每个调用的结果,你将浪费时间计算两次相同的事情……

顺便说一句:这段代码非常“焦虑”,并且因为规范说分配表达式(cache [n] = …)计算到指定的值,你正在返回cache [n].

猜你在找的JavaScript相关文章