摘要:采用的生成非波拉契數列提供了原生的支持,語法非常有特色,關鍵字后面緊跟一個星號。的詳細介紹參考官網先看如何用這個黑科技重新實現非波拉契樹立的生成。在這個內部,我們定義了一個無限循環,用于計算非波拉契數列。
程序員面試系列
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...*
先看如何用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的原創技術文章,請關注公眾號"汪子熙"或者掃描下面二維碼:
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/98589.html
摘要:描述斐波那契數列由列昂納多斐波那契以兔子繁殖為例子而引入,故又稱為兔子數列。這個數列從第項開始,每一項都等于前兩項之和。遞歸版本遞歸版本使用傳參及默認參數,減少冗余元算的同時也減少了函數調用。 描述 斐波那契數列:1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, ... 由列昂納多·斐波那契(Leonardoda Fibonacci)以兔子繁殖為例子...
摘要:今天去面試筆試題斐波那契數列實現,雖然很簡單。回來想想既然算法這么重要那就從這個開始來記錄自己的算法庫吧。在數學上,斐波納契數列以如下被以遞歸的方法定義,,。斐波拉契算法規律很簡單,,觀察下數列值就很容易總結出來了。 一、寫在前面 算法這塊對于大多數程序員(包括我)來說可能都是一個薄弱的地方,如何彌補尼? 每個人都知道那就是學習、特別是算法沒有任何捷徑可走。 在這記錄平時自己工作和生...
摘要:根據該規則,返回第個斐波那契數。尾遞歸函數調用自身,稱為遞歸。一個前端眼中的斐波那契數列解斐波那契數列的實用解法調用棧尾遞歸和手動優化尾調用優化譯我從用寫斐波那契生成器中學到的令人驚訝的件事 斐波那契數列是以下一系列數字: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, ... 在種子數字 0 和 1 ...
摘要:高階函數函數式編程中,接受函數作為參數,或者返回一個函數作為結果的函數通常就被稱為高階函數。均屬于高階函數,高階函數并不神秘,我們日常編程也會用到。參考演算函數式編程指南入門康托爾哥德爾圖靈永恒的金色對角線原文函數與演算 緣起 造了一個輪子,根據GitHub項目地址,生成項目目錄樹,直觀的展現項目結構,以便于介紹項目。歡迎Star。 repository-tree 技術棧: ES6 ...
摘要:在上做了一道斐波那契數列求和的題目,做完之后做了一些簡單的優化和用另一種方法實現。動態規劃解決方案斐波那契數列求和除了可以用遞歸的方法解決,還可以用動態規劃的方法解決。 在codewars上做了一道斐波那契數列求和的題目,做完之后做了一些簡單的優化和用另一種方法實現。 題目 function fibonacci(n) { if(n==0 || n == 1) r...
閱讀 2784·2021-09-01 10:30
閱讀 1680·2019-08-30 15:52
閱讀 965·2019-08-29 18:40
閱讀 1116·2019-08-28 18:30
閱讀 2391·2019-08-23 17:19
閱讀 1321·2019-08-23 16:25
閱讀 2700·2019-08-23 16:18
閱讀 2977·2019-08-23 13:53