通过增加缓存优化斐波那契递归的冗余计算

一、python

斐波那契数列的递归实现存在大量的冗余计算。例如,为了计算fib(n),我们需要计算fib(n-1)和fib(n-2),但是在计算fib(n-1)的过程中,我们又会重复计算fib(n-2)。当n的值很大时,这种冗余计算会消耗大量的计算资源。

为了解决这个问题,我们可以使用一种称为“记忆化”(Memoization)的技术。记忆化是一种优化技术,它将之前计算的结果存储起来,以便在需要时重新使用,而不是重新计算。

在斐波那契数列的递归实现中,我们可以创建一个缓存(通常是一个字典或数组),用于存储已经计算过的斐波那契数。每次计算新的斐波那契数时,我们首先检查缓存中是否已经存在该结果。如果存在,我们直接返回缓存中的结果,避免了冗余计算。如果不存在,我们进行计算,并将结果存储在缓存中,以便将来使用。

以下是一个使用Python实现的带有记忆化的斐波那契数列递归函数:

def fibonacci(n, cache={}):if n in cache:return cache[n]elif n <= 2:cache[n] = 1else:cache[n] = fibonacci(n-1, cache) + fibonacci(n-2, cache)return cache[n]

在这个函数中,我们使用了一个名为`cache`的字典作为缓存。每次调用函数时,我们首先检查`n`是否已经在`cache`中。如果是,我们直接返回`cache[n]`。否则,我们计算`fibonacci(n)`,并将结果存储在`cache`中。注意,我们在递归调用`fibonacci(n-1, cache)`和`fibonacci(n-2, cache)`时也传递了`cache`,以便在这些递归调用中也可以使用缓存。

二、go

斐波那契数列的递归实现因为重复地计算了很多子问题而效率比较低。这是一个典型的动态规划问题,可以通过“备忘录”方法优化,即在递归过程中记录已经计算过的斐波那契数,避免重复计算。
这里给一个使用备忘录优化斐波那契计算的Go代码示例:

package mainimport ("fmt"
)// 计算斐波那契数列的函数,使用备忘录优化递归
func fibonacci(n int, memo map[int]int) int {// 如果这个值已经计算过,直接从备忘录中返回if val, found := memo[n]; found {return val}// 边界条件if n <= 1 {return n}// 递归计算result := fibonacci(n-1, memo) + fibonacci(n-2, memo)// 将计算结果保存到备忘录memo[n] = resultreturn result
}func main() {// 初始化备忘录,用于存储已经计算过的斐波那契数memo := make(map[int]int)// 计算并打印第10个斐波那契数fmt.Println(fibonacci(10, memo))
}

在本例中,备忘录 memo 是一个Go语言的映射(map),它的键(key)是正在计算的 n 的值,而值(value)是对应斐波那契数。在函数 fibonacci 中,如果我们发现已经计算过了,就直接返回存储在 memo 中的结果。如果没有计算过,我们就计算它,并将结果保存到 memo 中,以便后续使用。
这种方法显著减少了计算量,因为每个斐波那契数值只计算一次。递归函数现在有线性的时间复杂度 O(n),而不是没有优化的递归版本的指数时间复杂度。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/466803.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Ubuntu Desktop 删除文件

Ubuntu Desktop 删除文件 1. right mouse click on the file -> Move to Trash2. right mouse click on the file -> DeleteReferences 1. right mouse click on the file -> Move to Trash ​ 2. right mouse click on the file -> Delete ​​​ References …

带你了解软件系统架构的演变

随着信息技术的飞速发展&#xff0c;软件系统架构作为支撑软件系统的核心框架&#xff0c;也在不断地演变和进步。本文旨在带你了解软件系统架构的发展历程&#xff0c;从而更好地理解现代软件系统的构建和设计。 一、单体应用架构 单体应用架构是最早的软件系统架构形式&…

关于在分布式环境中RVN和使用场景的介绍3

简介 在《关于在分布式环境中RVN和使用场景的介绍2》和《关于在分布式环境中RVN和使用场景的介绍1》中我们介绍了RVN的概念和在一些具体用例中的使用。在本文中我们讨论一下在分布式环境中使用RVN需要注意的问题。 问题 我们在收到一条待处理的事件时&#xff0c;需要检查该…

架构(十三)动态本地锁

一、引言 加锁大家都知道&#xff0c;但是目前提供动态锁的基本都是分布式锁&#xff0c;根据订单或者某个收费款项进行加锁。比如这个1订单要收刷卡费用&#xff0c;那就OREDER_1做为key丢到redis进行分布式加锁。这也是当下分布式锁最流行的方式。 但是对于平台项目或者一些并…

【深度学习】基于多层感知机的手写数字识别

案例2&#xff1a;构建自己的多层感知机: MNIST手写数字识别 相关知识点: numpy科学计算包&#xff0c;如向量化操作&#xff0c;广播机制等 1 任务目标 1.1 数据集简介 ​ MNIST手写数字识别数据集是图像分类领域最常用的数据集之一&#xff0c;它包含60,000张训练图片&am…

fatal error: rtiostream_utils.h: No such file or directory, rtiostream.h

fatal error: rtiostream_utils.h: No such file or directory 我的设置&#xff1a;

C语言rand随机数知识解析和猜数字小游戏

rand随机数 rand C语言中提供了一个可以随机生成一个随机数的函数&#xff1a;rand&#xff08;&#xff09; 函数原型&#xff1a; int rand(void);rand函数返回的值的区间是&#xff1a;0~RAND_MAX(32767)之间。大部分编译器都是32767。 #include<stdlib.h> int ma…

linux系统下vscode portable版本的python环境搭建003:venv

这里写自定义目录标题 python安装方案一. 使用源码安装&#xff08;有[构建工具](https://blog.csdn.net/ResumeProject/article/details/136095629)的情况下&#xff09;方案二.使用系统包管理器 虚拟环境安装TESTCG 本文目的&#xff1a;希望在获得一个新的系统之后&#xff…

vue 向某个网址 传递数据

1. 需求 现在有一个网站需要 配置上另一个网站的东西 类似这样的东西吧 就是我需要再一个网站上 右边或者其他地方 放另一个页面的地址 这个地址需要给我传递东西 或我这个网站给其他的网站传递token了 id等 2.解决 window.parent.postMessage({ token: loginRes.token, id:…

【Java程序设计】【C00249】基于Springboot的私人健身与教练预约管理系统(有论文)

基于Springboot的私人健身与教练预约管理系统&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的私人健身与教练预约管理系统 本系统分为系统功能模块、管理员功能模块、教练功能模块以及用户功能模块。 系统功能模…

2.11日学习打卡----初学RocketMQ(二)

2.11日学习打卡 一. RocketMQ整合springboot 首先配置pom.xml文件 <dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><scope>annotationProcessor</scope></dependency><dependency>…