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

时间:2015-06-22 01:08:29

标签: javascript variables fibonacci

我正在尝试在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,1]

为什么?

2 个答案:

答案 0 :(得分:2)

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

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 - 用[ 0 ]
  • 初始化的纤维系列
  • i - 用于终止递归的递减迭代器,用n初始化
  • a - 第一个用0
  • 初始化的原始数字
  • b - 第二个原始数字,用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-combinator,您可以获得相同功能的精简版

// 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 ]

酷!

答案 1 :(得分:1)

您必须在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);