斐波那契数列的认识
先来看看什么是斐波那契数列。
斐波那契数列指的是这样一个数列 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368[1]
特别指出:第0项是0,第1项是第一个1。
这个数列从第3项开始,每一项都等于前两项之和。
传统的递归方法解决会造成大量的重复计算。具体代码如下:
//f(n) = f(n-1) + f(n - 2)
var count = 0;
function fib(n){
count ++;
if(n <= 2){
return 1;
}
return fib(n - 1) + fib(n - 2);
}
fib(5);
console.log(count);
count = 0;
fib(6);
console.log(count);
count = 0;
fib(20);
console.log(count);
count = 0;
fib(21);
console.log(count);
count = 0;
//使用数组存储数列,虽然可以提升性能,但是有局限性
//可以求5的 也可以求10的,但是要求100呢 100000呢
var arr = [1, 1, 2, 3, 5, 8, 13, 21, 34];
arr[0];
arr[1];
arr[100];
如果按照传统的递归方法处理斐波那契数列问题,就会造成大量的重复计算,造成内存占用过多的现象。接下来,我们来做改进。使用缓存数组的方式:
//定义一个缓存数组,储存已经计算出来的斐波那契数组。
//计算步骤
//1.先从缓存数组中获取想要的数据,如果获取到了就直接使用。
//2.如果没有获取到就计算后传入缓存数组
var cache = [];
var count = 0;
function fib(n){
count++;
//判断是否存在于缓存数组中,存在就直接返回
if(cache[n]!=undefined){
return cache[n];
}
//不存在就计算
if(n<=2){
//将计算结果存入数组
cache[n] = 1;
return cache[n];
}
var temp = fib(n-1)+fib(n-2);
cache[n]=temp;
return temp;
}
return fib;
console.log(fib(6));
//更进一步,用构造函数的方式来创建缓存函数。
var count =0 ;
function createFib(){
var cache = [];
function fib(n){
count ++;
//1.从cache中获取数据
if(cache[n] !== undefined){
//如果缓存中有 直接返回
return cache[n];
}
//如果缓存中没有 就计算
if(n <= 2){
//把计算结果存入数组
cache[n] = 1;
return 1;
}
var temp = fib(n - 1) + fib(n - 2);
//把计算结果存入数组
cache[n] = temp;
return temp;
}
return fib;
}
如上面缓存函数所示,可以解决多次计算的问题。这里我们引入缓存容器。类比上面的代码。
//创建缓存容器
function CreateCache(){
var chche{};
return function(key,value){
//如果传了值,就说明是设置值
if(value!=undefined){
//将值设置并传入缓存容器中
cache[key]=value;
return cache[key];
}
//如果只传了键,就说明是获取值。
else{
return cache[key];
}
}
}
//将缓存容器应用在斐波那契中
var count =0;
function CreateFib(){
//创建缓存容器
var fibCache = CreateCache();
//计算方法函数fib
function fib(n){
count++;
//判断缓存容器中是否存在
if(fibCache(n)!=undefined){
//如果存在,就直接返回使用
return fibCache(n);
}
//如果不存在就计算
if(n<=2){
//将计算结果存入容器
fibCache(n,1);
return 1;
}
var temp = fib(n-1)+fib(n-2);
fibCache(n,temp);
return temp;
}
return fib;
}
//测试一下
var fib = CreateFib();
fib(5);
console.log(count);
count = 0;
fib(6);
console.log(count);
count = 0;
fib(20);
console.log(count);
count = 0;
fib(21);
console.log(count);
count = 0;