使用先前声明的变量在fib序列javascript中查找第n个值

find nth value in fib sequence javascript using previously declared variables

本文关键字:javascript 序列 查找 个值 fib 声明 变量      更新时间:2023-09-26

我试图在javascript中找到fib序列的第n个值,但在此之前我遇到了另一个问题,我正在努力理解原因。

function nthFib(n) {
  var fib = [0, 1];
  var l = fib[fib.length-1];
  var s = fib[fib.length-2];  
  while(fib.length < n) {
    fib.push(fib[fib.length-1] + fib[fib.length-2]);
  }
  console.log(fib); 
}
nthFib(5);

现在,当我控制台日志时,我得到了我想要的,即阵列构建:[0,1,1,2,3]

但如果我在while循环中这样做,以获得更干净的代码:

while(fib.length < n) {
  fib.push(s + l);
}

我想我的while循环无法访问这些变量,然后我得到了这样的结果:[0,1,1,1]

为什么?

我认为这是一个更好的函数,因为它使用了具有适当尾部递归的线性迭代过程

function fib(n) {
  function iter(xs, i, a, b) {
    if (i === 0) return xs;
    return iter(xs.concat(b), i-1, b, a+b);
  }
  return iter([0], n, 0, 1);
}

示例

fib(0);
//=> [ 0 ]
fib(1);
//=> [ 0, 1 ]
fib(2);
//=> [ 0, 1, 1 ]
fib(3);
//=> [ 0, 1, 1, 2 ]
fib(4);
//=> [ 0, 1, 1, 2, 3 ]
fib(5);
//=> [ 0, 1, 1, 2, 3, 5 ]
fib(6);
//=> [ 0, 1, 1, 2, 3, 5, 8 ]
fib(10);
//=> [ 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55 ]

解释

iter函数采用4个状态变量

  • xs-fib级数,用[ 0 ]初始化
  • i-用于终止递归的递减迭代器,用n初始化
  • a-第一个fib编号,用0初始化
  • b-第二个fib编号,用1初始化

其工作方式是,一旦i到达0,就会返回xs

让我们看看fib(5)是如何计算的

//   xs             i  a  b
// -----------------------------
iter([0],           5, 0, 1);
iter([0,1],         4, 1, 1);
iter([0,1,1],       3, 1, 2);
iter([0,1,1,2],     2, 2, 3);
iter([0,1,1,2,3],   1, 3, 5);
iter([0,1,1,2,3,5], 0, 5, 8);
// -----------------------------
//=> [0,1,1,2,3,5]

ES6

使用带有ES6的U组合子,您可以获得相同函数的精简版本

// ES6
let fib = n => (
  f => f(f, [0], n, 0, 1)
)(
  (f, xs, i, a, b) => i === 0 ? xs : f(f, xs.concat(b), i-1, b, a+b)
);
fib(10);
//=> [ 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55 ]

酷!

您必须在while循环中修改s, l。看看这个代码。

function nthFib(n) {
  var fib = [0, 1];

  while(fib.length < n) {
      var l = fib[fib.length-1];
      var s = fib[fib.length-2];  
      fib.push(s + l);
  }
  console.log(fib); 
}
nthFib(5);