JS编程题:输出斐波那契数列的某一项

方法一

使用递归

function f1(num) {
     
  console.count('函数调用次数');
  if (num === 1 || num === 2) {
     
    return 1;
  }
  return f1(num - 1) + f1(num - 2);
}

console.log('第10项:',f1(10));

计算斐波那契数列的第10项,函数被递归调用了109次:
JS编程题:输出斐波那契数列的某一项_第1张图片
上边的 if 判断语句也可以用三元表达式来代替:

function f1(num) {
     
   return num < 3 ? 1 : f1(num - 1) + f1(num - 2);
}

方法二

在方法一中代码是否有大量重复的计算

  • 比如计算f(5),要计算f(3) 和 f(4)
  • 计算f(6)要计算f(5)和f(4),而计算f(5),又要计算f(3) 和 f(4) ,……

那么我们是否可以想一种方法将已经计算出来的结果缓存起来呢?

方法二依然使用递归:

let cache = {
     };
function f2(num) {
     
  console.count('函数调用次数');
  if (cache[num]) {
     
    return cache[num];
  }

  let v = num < 3 ? 1 : f2(num - 1) + f2(num - 2);
  cache[num] = v;      // 每次算出一个值,就把这个值存入缓存对象
  console.log(cache);
  return v;           // 注意要返回计算结果
}

console.log(f2(10));
console.log(cache);

计算斐波那契数列的第10项,函数只被调用了17次:
JS编程题:输出斐波那契数列的某一项_第2张图片
这里再解释一下为什么最后一定要返回计算结果,这里是一个坑,我一开始写的时候,以为不用返回计算结果,然后拿到的数据里边有几项NaN,很纳闷。原因就在于:如果某一项一开始没有在缓存中,然后在将计算结果存入缓存后,我们又没有返回计算结果,则会默认返回undefined,而undefined加一个数字的值是NaN。并且如果计算f(4),那么f(4)的结果就是undefined,因为我们没有返回。

我们计算第4项,打个断点调试一下,如图所示:

let cache = {
     };
function f2(num) {
     
  if (cache[num]) {
     
    return cache[num];
  }

  let v = num < 3 ? 1 : f2(num - 1) + f2(num - 2);
  cache[num] = v;
  console.log(cache);
  // return v;
}

console.log('第4项:',f2(4));
console.log(cache);

方法三

使用数组,有种自带缓存的感觉

function f3(num) {
     
  let arr = [1, 1];
  while (arr.length < num) {
     
    arr.push(arr[arr.length - 1] + arr[arr.length - 2])
  }
  return arr;
}

console.log(f3(10));

结果如图:
在这里插入图片描述

你可能感兴趣的:(题,js,缓存)