一般斐波納契數列採用遞迴或是陣列快取的方式,這裡的方法不考慮重複計算斐波納契數列的情況。
fibonacci 數列定義,檢視百度百科的解釋>>
n = 1,2 時,fib(n) = 1
n > 2 時,fib(n) = fib(n-2) + fib(n-1)
1、遞迴
function Fib(n) {
return n < 2 ? n : (Fib(n - 1) + Fib(n - 2));
}
2、陣列快取
var IterMemoFib = function() {
var cache = [1, 1];
return function (n) {
if (n >= cache.length) {
for (var i = cache.length; i < n ; i++ ) {
cache[i] = cache[i - 2] + cache[i - 1];
}
}
return cache[n - 1];
}
}();
3、直接使用加法
function fib(n) {
if (n < 2) {
return 1;
}
var a = 1, b = 1;
for (var i = 2; i < n - 1 ;i++ ) {
b = a + b;
a = b - a;
}
return a + b;
}
對比:
如果只使用一次運算,第三種方法速度最快;
如果多次使用,第二種方法明顯優於其它兩種;
在n較大的情況下不推薦使用第一種;n為10*10000的時候遞迴就已經報記憶體溢位了
下面是在IE8下測試的結果(n為100W):
如果只需要計算一次,第三種方法應該是最優的,而且當n越大的時候,陣列佔有的記憶體空間也將越大。
完整程式碼:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title> new document </title>
<meta name="generator" content="editplus" />
<meta name="author" content="" />
<meta name="keywords" content="" />
<meta name="description" content="" />
<meta http-equiv='content-type' content='text/html;charset=utf-8' />
</head>
<body>
<script type="text/javascript">
function Fib(n) {
return n < 2 ? n : (Fib(n - 1) + Fib(n - 2));
}
var IterMemoFib = function() {
var cache = [1, 1];
return function (n) {
if (n >= cache.length) {
for (var i = cache.length; i < n ; i++ ) {
cache[i] = cache[i - 2] + cache[i - 1];
}
}
return cache[n - 1];
}
}();
function fib(n) {
if (n < 2) {
return 1;
}
var a = 1, b = 1;
for (var i = 2; i < n - 1 ;i++ ) {
b = a + b;
a = b - a;
}
return a + b;
}
var num = 10000*100;
function test(fn, n) {
var date = +new Date();
fn(n);
return new Date().getTime() - date;
}
//document.write('第一種方法,運算時間:' + test(Fib, num) + '<br/>');
document.write('第二種方法,運算時間:' + test(IterMemoFib, num) + '<br/>');
document.write('第三種方法,運算時間:' + test(fib, num));
document.write('<br/><br/><br/>');
document.write('第二種方法,運算時間:' + test(IterMemoFib, num) + '<br/>');
document.write('第三種方法,運算時間:' + test(fib, num));
</script>
</body>
</html>