程序员面试系列

Java面试系列-webapp文件夹和WebContent文件夹的区别?

程序员面试系列:Spring MVC能响应HTTP请求的原因?

Java程序员面试系列-什么是Java Marker Interface(标记接口)

使用JDK自带的工具jstack找出造成运行程序死锁的原因

编程面试题:编写一个会造成数据库死锁的应用

JavaScript面试系列:JavaScript设计模式之桥接模式和懒加载

面试题:用JavaScript开发一个函数,打印非波拉契数列。

我们只要记住非波拉契数列的计算公式,就不难写出来了:

F(0)=1,F(1)=1, F(n)=F(n-1)+F(n-2)

我写的JavaScript代码如下:


var fib = function (a, b) { var _current = a + b; return { current: _current, next: function () { return fib(b, _current); }
}
}

把当前这一轮的计算结果存储到第二行的变量_current里,并通过属性current返回给调用者。返回的json对象除了current属性外,还有另一个属性next,指向一个闭包函数调用。一旦next指向的函数再次被调用,则会再次触发数列的计算。

var generator = fib(1,1);

// 前一行调用fib(1,1)计算1+1的结果为2,将2存储到_current里通过current属性返回,所以打印2

// 同时返回next函数,函数体为return fib(b, _current); 此时b为1,_current为2

console.log(generator.current);

// 一旦执行next函数,则执行其指向的return fib(b, _current); 1 + 2 = 3

var result = generator.next();

console.log(result.current); // 打印3

如果要打印10个非波拉契数列的值,意味着我要重复调用9次fib函数,太麻烦。于是我写了个函数把fib调用包裹起来。

这个包裹函数有两个输入参数,n为希望生成非波拉契数列元素的个数,第二个参数sequence接受一个函数。

var take = function(n, sequence) {

    var result = [];

    var temp = sequence;

    for (var i = 0; i < n; i++) {

         result.push(temp.current);

         temp = temp.next();

    }

   return result;

}

现在我只需要一行语句,就能打印10个非波拉契数列的元素出来。

console.log(take(10, fib(1,1)));

采用ES6的GeneratorFunction生成非波拉契数列

ES6提供了原生GeneratorFunction的支持,语法非常有特色,关键字function后面紧跟一个星号。GeneratorFunction的详细介绍参考官网:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*

先看如何用GeneratorFunction这个黑科技重新实现非波拉契树立的生成。代码如下:

var fib_generator = function *(){

     var current = 0, next = 1;

      while(true) {

          [next, current] = [next+current, next];

          yield current;

     }

}

var fib = fib_generator();

for(var i = 0; i < 10; i++){

      console.log(fib.next().value);

}

第5行从语义上非常清晰地体现出了非波拉契数列的计算公式:

F(n)=F(n-1)+F(n-2)

然而它是包含在一个while(true)的无限循环内的,所以这段代码是如何工作的呢?

最好的学习办法就是单步调试。

代码第40行到第47行,我们使用了ES6 function*关键字得到了一个"function generator"。在这个generator内部,我们定义了一个无限循环,用于计算非波拉契数列。

第49行,我们用()调用了这个generator,将结果存储在变量fib里。直到此时,function generator的实现体,即代码41~45行还没有得到执行。

实际上,49行的变量lib只是维护了一个指向fib_generator的ITERATOR指针。

这个ITERATOR自带了一个名为next的方法,是ES6的原生实现,大家看上图调试器里的fib.next显示的是native code。Functiongenerator的神奇之处在于,当next方法被调用一次,则generator内部的函数体也只会执行一次。

单步执行,执行一次next方法:

注意调用栈,此时我们已经进入fib_generator函数体内部了:

一旦在FunctionGenerator实现体内部执行到yield关键字,则当前计算结果作为返回值返回给consumer。也就是说,一旦执行遇到yield,则自动从无限循环中退出。

下列简单的循环会打印10个非波拉契数列的元素:

for(var i = 0; i < 10; i++){

     var currentResult = fib.next();

      console.log(currentResult.value);

}

从上面的代码能看出,yield关键字返回一个json对象给消费者,该对象有个名为name的属性,包含的是具体计算的数值。Json对象的另一个属性名为done,类型为boolean,意思是这个FunctionGenerator的函数体执行是否已经结束。在我的这个例子里,每次next调用的yield返回的Json对象的done属性都为false,因为我的FunctionGenerator内部是一个无限循环。

采用ES6的FunctionGenerator打印出的结果和常规写法一致。

相信您面试的时候,如果能用ES6的FunctionGenerator完成这道题目,一定能让面试官对您刮目相看。

我写的程序员面试系列

Java面试系列-webapp文件夹和WebContent文件夹的区别?

程序员面试系列:Spring MVC能响应HTTP请求的原因?

Java程序员面试系列-什么是Java Marker Interface(标记接口)

使用JDK自带的工具jstack找出造成运行程序死锁的原因

编程面试题:编写一个会造成数据库死锁的应用

JavaScript面试系列:JavaScript设计模式之桥接模式和懒加载

要获取更多Jerry的原创技术文章,请关注公众号"汪子熙"或者扫描下面二维码:

使用JavaScript ES6的新特性计算Fibonacci(非波拉契数列)的更多相关文章

  1. 如何在ABAP里用函数式编程思想打印出非波拉契Fibonacci(数列)

    在JavaScript里可以用ES6提供的FunctionGenerator这种黑科技来打印非波拉契数列,具体细节参考我这篇文章. 在ABAP里也有很多种方式实现这个需求. 下面这个report分别用 ...

  2. 关于斐波拉契数列(Fibonacci)

    斐波那契数列指的是这样一个数列 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233,377,610,987,1597,2584,4181,6765,10 ...

  3. python的生成器(斐波拉契数列(Fibonacci))

    代码: 函数版本: #斐波拉契数列(Fibonacci) def fib(max): n=0 a,b=0,1 while n < max: a,b = b,a+b n = n+1 return ...

  4. 斐波拉契数列(用JavaScript和Python实现)

    1.用JavaScript 判断斐波拉契数列第n个数是多少 //需求:封装一个函数,求斐波那契数列的第n项 //斐波拉契数列 var n=parseInt(prompt("输入你想知道的斐波 ...

  5. 递归算法之Fibonacci 斐波那契数列第n个数的求解

    Fibonacci 斐波那契数列第n个数的求解,也可以用递归和非递归的形式实现,具体如下,dart语言实现. int fibonacci(int n) { if (n <= 0) throw S ...

  6. lintcode:Fibonacci 斐波纳契数列

    题目: 斐波纳契数列 查找斐波纳契数列中第 N 个数. 所谓的斐波纳契数列是指: 前2个数是 0 和 1 . 第 i 个数是第 i-1 个数和第i-2 个数的和. 斐波纳契数列的前10个数字是: 0, ...

  7. 算法导论-求(Fibonacci)斐波那契数列算法对比

    目录 1.斐波那契数列(Fibonacci)介绍 2.朴素递归算法(Naive recursive algorithm) 3.朴素递归平方算法(Naive recursive squaring) 4 ...

  8. 斐波拉契数列(Fibonacci)--用生成器生成数列

    斐波那契数列(Fibonacci sequence),又称黄金分割数列.因数学家列昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为"兔子数列&qu ...

  9. Fibonacci(斐波那契数列)的最佳实践方式(JavaScript)

    1)低级版本 var fibonacci = function(n) { if (n == 0 || n == 1) { return n; } else { return fibonacci(n - ...

随机推荐

  1. 有关如何线程安全的使用map(hashMap)

    最近在写一个多线程中控制输出顺序的系统中的一个代码,使用了map的数据结构.具体的业务是需要一个单例的对象,然后需要在多线程的环境下实现添加和删除的操作.部分代码如下: public class Up ...

  2. json对象和json数组

    json字符串对象和json字符串数组:JSONArray跟JSONObject的区别就是JSONArray比JSONObject多中括号[] jsonObject: "Row": ...

  3. 20个Flutter实例视频教程-第03节: 不规则底部工具栏制作-1

    第03节: 不规则底部工具栏制作-1 博客地址: https://jspang.com/post/flutterDemo.html#toc-973 视频地址: https://www.bilibili ...

  4. Flutter实战视频-移动电商-60.购物车_全选按钮的交互效果制作

    60.购物车_全选按钮的交互效果制作 主要做全选和复选框的这两个功能 provide/cart.dart 业务逻辑写到provide里面 先持久化取出来字符串,把字符串编程list.循环list ca ...

  5. 【BZOJ1855】[Scoi2010] 股票交易

    →BZOJ任意门← 很显然的动态规划题(笑) 容易想到DP的数组 f[i][j] 表示第i天手上有j股股票时能赚到最多的钱. 接下来就是转移了,有这么多变量一定要看清楚,仔细地分情况讨论. 每次转移时 ...

  6. random 库

    random 是使用随机数的python 标准库 ——为随机数:采用梅森旋转算法生成的(伪)随机序列中的元素 —— import random 基本随机数函数:seed(),random() 扩展随机 ...

  7. Servlet | 访问不同格式文件(PDF、doc)

    核心代码 //设置响应内容类型为PDF类型 response.setContentType("application/pdf"); request.getRequestDispat ...

  8. Codeforces Round #532(Div. 2) A.Roman and Browser

    链接:https://codeforces.com/contest/1100/problem/A 题意: 给定n,k. 给定一串由正负1组成的数. 任选b,c = b + i*k(i为任意整数).将c ...

  9. Codeforces Round #397 by Kaspersky Lab and Barcelona Bootcamp (Div. 1 + Div. 2 combined) C

    Misha and Vanya have played several table tennis sets. Each set consists of several serves, each ser ...

  10. linux系统下安装Git

    Git(读音为/gɪt/.)是一个开源的分布式版本控制系统,可以有效.高速地处理从很小到非常大的项目版本管理.而国外的GitHub和国内的Coding都是项目的托管平台.Git 是 Linus Tor ...