php切割夫数列递归,菲波那切数列的案例(递归,闭包)

斐波那契数列(Fibonacci sequence),又称黄金分割数列、因数学家莱昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,

// 斐波那契的案例

// 兔子数:

// 月份:1 2 3 4 5 6 7 8 9 10 11

// 数量:1 1 2 3 5 8 13 21 34 55 89

复制代码

青铜

function fib(n){

if(n === 1 || n === 2) return 1

return fib(n - 1) + fib(n - 2)

}

复制代码

白银(提高性能)

看一下性能怎么样?

let count = 0 // 计数 : 统计fib函数递归了多少次

function fib(n){

count++

if(n === 1 || n === 2) return 1

return fib(n - 1) + fib(n - 2)

}

console.log(fib(40)); // 102334155

console.log(count); // 204668309

复制代码

我去计算到40个月的时候count居然跑了204668309次,怎么办?

// 缓存: (cache), 是个存储数据的容器

// 在js里面如何去实现缓存: 用数组或对象来做缓存容器,使用键来存值,还可以通过键来取值,

// 可以实现即能存储值还可以取值。

// 使用缓存的思路:

// 1. 不是先去计算结果,先判断缓存中是否有对应的数据

// 2. 如果有,直接取出缓存中的对应数据

// 3. 如果没有,就去先计算,把计算结果存储到缓存中,方便下次使用

// 在这个案例中,如何去使用缓存

let cache = {

// 把月份作为键,把月份对应的数量作为值

// 1: 1,

// 2: 1,

// 3: 2,

// 4: 3

};

// 使用递归去计算兔子第10个月的数量

let count = 0 // 计数 : 统计fib函数递归了多少次

function fib(n){

count++

// 求出第n个月的兔子数量

// 2. 结束

if(n === 1 || n === 2) return 1

if (cache[n]) {

// 说明了: 缓存中有该月份的数量值,直接取出缓存中的数据

return cache[n]

} else {

// 说明缓存中没有该月份的数量

let ret = fib(n - 1) + fib(n - 2) // 计算的结果

// 把结果存储到缓存中

cache[n] = ret

// 把结果给返回出去

return ret

}

}

console.log(fib(40));

console.log(count);

// 月份 优化前的次数 优化后的次数

// n = 10; count = 109 17

// n = 11; count = 177 19

// n = 12; count = 287 21

// n = 20; count = 13529

// n = 21; count = 21891

// n = 40; count = 204668309 77

复制代码

黄金(安全问题)

思考cache 暴露在全局中,如果有人修改了怎么办?

// 使用闭包来保护cache数据的安全

function outer(){

// 在这个案例中,如何去使用缓存

// 缓存里面的数据是计算得出的,我们应该充分信赖缓存里面的数据

// 缓存里面的数据应该是绝对正确而且是不能被随意修改的

let cache = {

// 把月份作为键,把月份对应的数量作为值

// 1: 1,

// 2: 1,

// 3: 2,

// 4: 3

};

// 使用递归去计算兔子第10个月的数量

function fib(n){

// 求出第n个月的兔子数量

// 2. 结束

if(n === 1 || n === 2) return 1

if (cache[n]) {

// 说明了: 缓存中有该月份的数量值,直接取出缓存中的数据

return cache[n]

}

return cache[n] = fib(n - 1) + fib(n - 2)

}

return fib

}

let ret = outer()

console.log(ret(40))

复制代码

总结

对于斐波那契案例使用到的技术点:

递归: 计算结果

缓存: 存储计算的数据

闭包: 保护缓存数据的安全

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值