斐波那契数列

2021-03-11  本文已影响0人  McDu
function* fibs() {
  let a = 0;
  let b = 1;
  while (true) {
    yield a;
    [a, b] = [b, a + b];
  }
}

let [first, second, third, fourth, fifth, sixth, seven] = fibs();
sixth // 5
seven // 8

参考
非尾递归的 Fibonacci 数列实现如下:

function fibs(n) {
    if(n <= 1) {
      return 1;
    } 
    return fibs(n - 1) + fibs(n - 2)
}

尾递归优化过的 Fibonacci 数列实现:

function fibs2(n, ac1 = 1, ac2 = 1) {
    if(n <= 1) {
      return ac2
    }

    return fibs2(n - 1, ac2, ac1 + ac2)
}

尾递归的实现,往往需要改写递归函数,确保最后一步只调用自身。做到这一点的方法,就是把所有用到的内部变量改写成函数的参数。比如上面的例子,阶乘函数 factorial 需要用到一个中间变量total,那就把这个中间变量改写成函数的参数。这样做的缺点就是不太直观,第一眼很难看出来,为什么计算5的阶乘,需要传入两个参数5和1?

两个方法可以解决这个问题。方法一是在尾递归函数之外,再提供一个正常形式的函数。

阶乘

function factorial(n) {
    if(n === 1) {
      return 1
    }

    return n * factorial(n - 1)
}

尾递归优化之柯里化

function tailFactorial(n, total) {
    if(n === 1)  {
        return total
    }
    return tailFactorial(n - 1, n * total)
}

function factorial(n) {
    return tailFactorial(n, 1)
}
function currying(fn, n) {
    return function(m) {
        return fn.call(this, m, n)
    } 
}


function tailFactorial(n, total) {
    if(n === 1) return total;
    return tailFactorial(n - 1, n * total)
}

function factorial = currying(tailFactorial, 1)

es6 默认值

function factorial(n, total = 1) {
    if (n === 1) {
      return total;
    }
    return factorial(n - 1, n * total)
}
上一篇 下一篇

猜你喜欢

热点阅读