Fibonacci求解

2024-06-19 15:38
文章标签 fibonacci 求解

本文主要是介绍Fibonacci求解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

        想想刚刚学C语言的时候,一开始接触递归的时候,感觉这东西实在是太不可思议了,可以将程序变得异常简洁并且非常易于理解。然后啥问题都想问递归上去扯,搞出个递归公式出来,问题就基本解决了大笑大笑大笑但是随着学习的深入,渐渐也道听途说到递归也不是那么好,因为对函数的递归调用会造成巨大的开销而且程序的运行速度也会受到限制。最近也上了些数据结构,发现书上给出递归算法的同时也会给出非递归算法!瞬间感觉,非递归好像更牛逼的样子!(关于数据结构的博文接下来也会有的,应该会结合和算法导论的阅读,我会努力写出各种非递归算法的)其实,在运用递归算法的时候,你并不一定对整个结构有完美的把握,而非递归需要你对每个细节有更完美的把握,这不论对程序的理解还是编码能力都是巨大的提高。

      不知不觉居然扯了这么多生气生气生气其实我是来说说Fibonacci的快速求解的,结合了书上写的,已经在看书上的解法前自己写的一些程序(居然完全不一样!)。首先是把递归求解改为非递归啦,这个应该不代码,直接上代码也就不解释什么了。

unsigned long FIB_IT(unsigned long n)
{unsigned long f_1=1,f_2=1,i,temp;if(n==1||n==2)return 1;for(i=0;i<n-2;i++){temp=f_2;f_2=f_1+f_2;f_1=temp;}return f_2;
}

不过书上给出了一个用矩阵求解Fibonacci的方法,直接将O(n)的复杂度变为了O(lgn)。不过当初线代完全是靠考前刷题才拿的高分,考完就忘了,要是我估计一辈子也想不出这个方法的。其实思路也是挺简单的,附张图好了

只要知道矩阵的乘法就知道这个式子其实和Fibonacci的递推公式是一样的。因此一直推下去,就可以得到(Fn,Fn-1)


而那个n-2次方的矩阵,我们完全可以用上篇博文里的数值自乘的递归方法求解,而这也是这个程序速度更快的关键啦!下面还是结合代码来分析吧

unsigned long FIB_IT(unsigned long n)
{unsigned long aa,bb,cc,dd;if(n==1||n==2)return 1;Matrix(1UL,1UL,1UL,0UL,n-2,&aa,&bb,&cc,&dd);return aa+bb;
}void Matrix(unsigned long a,unsigned long b,unsigned long c,unsigned long d,\int n,unsigned long *aa,unsigned long *bb,unsigned long *cc,\unsigned long *dd)
{unsigned long a1,b1,c1,d1,ta,tb,tc,td;if(n==1){*aa=a,*bb=b,*cc=c,*dd=d;return;}Matrix(a,b,c,d,n>>1,&a1,&b1,&c1,&d1);*aa=ta=a1*a1+b1*c1;*bb=tb=a1*b1+b1*d1;*cc=tc=a1*c1+d1*c1;*dd=td=b1*c1+d1*d1;if(n&0x01)   {//*aa=a*(*aa)+b*(*cc);//*bb=a*(*bb)+b*(*dd);//*cc=c*(*aa)+d*(*cc);//*dd=c*(*bb)+d*(*dd);*aa=a*ta+b*tc;*bb=a*tb+b*td;*cc=c*ta+d*tc;*dd=c*tb+d*td;}
}

关键是那个递归函数Matrix,递归的边界值是n==1,那个时候只要将n-2次的那个矩阵返回就可以了。有一点要注意的是,当n为偶数的时候,恰好能分为两个一样的子矩阵,此时只要将子递归函数返回的矩阵自乘即可。不过如果n为奇数的话,因为子递归函数的参数是n/2,将其递归返回的子矩阵相乘在次数上与n还差1,所以还要在已求得的子矩阵乘积的基础上再乘一个(1,1,1,0)这个矩阵。在此时我就反了个非常非常低级的错误,代码就是被注释掉的那部分,竟然忘了赋值运算后值就变了= =差点debug到崩溃。

最后经过递归后,第一个Matrix返回的就是(1,1,1,0)的n-2次的矩阵啦,而Fn=a+b,Fn-1=c+d,看那个矩阵运算的式子就知道了。

为了检验它的速度我还真测试了一下,我求第1000个Fibonacci数100000次,用两种方法,出结果的速度真的是差很多的。也算再次感觉到了优秀算法的巨大魅力了吧大笑大笑大笑


这篇关于Fibonacci求解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1075445

相关文章

鹅算法(GOOSE Algorithm,GOOSE)求解复杂城市地形下无人机避障三维航迹规划,可以修改障碍物及起始点(Matlab代码)

一、鹅算法 鹅优化算法(GOOSE Algorithm,GOOSE)从鹅的休息和觅食行为获得灵感,当鹅听到任何奇怪的声音或动作时,它们会发出响亮的声音来唤醒群中的个体,并保证它们的安全。 参考文献 [1]Hamad R K, Rashid T A. GOOSE algorithm: a powerful optimization tool for real-world engineering

SQL求解两个时间差 时间类型 时间值

sql 求解两个时间差 SELECTDATEDIFF( Second, '2009-8-25 12:15:12', '2009-9-1 7:18:20') --返回相差秒数 SELECTDATEDIFF( Minute, '2009-9-1 6:15:12', '2009-9-1 7:18:20') --返回相差分钟数 SELECTDATEDIFF( Day, '2009-8

编写程序,采用辗转相除法求解两个正整数的最大公约数

--编写程序,采用辗转相除法求解两个正整数的最大公约数DECLARE @a int,@b intSELECT @a=12,@b=21DECLARE @temp intprint cast(@a as varchar(5))+'和'+cast(@b as varchar(5))+'的最大公约数是'if @a<@b --或者是select @temp=@a,@a=@b,@b=@tempb

【工具笔记】Microsoft数学求解器Math Solver

【工具笔记】Microsoft数学求解器Math Solver 工具笔记用于记录各种有用的工具,这里记录的是一个由Microsoft提供的数学求解器Math Solver。 可以用于求解代数,三角学,微积分,矩阵等各种数学问题,并且可以获取分步解释,查看如何解决问题并获取数学概念的定义,立即画出任何公式以可视化函数并了解变量之间的关系。还会搜索出相关的视频,练习题,类似问题等。 Math S

编译原理-各章典型题型+思路求解

第2章文法和语言习题 基础知识: 思路: 基础知识: 思路: 基础知识: 编译原理之 短语&直接短语&句柄 定义与区分_编译原理短语,直接短语,句柄-CSDN博客 思路: 题目: 基础解释:   简单来说: 上下文无关文法就是这个文法中所有的产生式左边只有一个非终结: 例如:S->Abc 上下文无关文法就是第一个产生式左

用栈来求解限制后的汉诺塔问题

用栈来求解限制后的汉诺塔问题(限制不能从最左侧的塔直接移动到最右侧,也不能从最右侧直接移动到最左侧,而是必须经过中间,求当塔有N层的时候,打印最优移动过程和最优移动总步数) import java.util.Stack;//用栈来求解限制后的汉诺塔问题(限制不能从最左侧的塔直接移动到最右侧,也不能从最右侧直接移动到最左侧,而是必须经过中间,求当塔有N层的时候,打印最优移动过程和最优移动总步数

线性代数习题求解复习

problem1: Section 2.2. Problem 20: Three planes can fail to have an intersection point, even if no planes are parallel. The system is singular if row 3 of A is a of the first two rows. Find a third

改进位删除谜题的求解方法

问题背景 给定长度为 n 的二进制向量,如何删除恰好 n/3 个位,使剩余二进制向量的不同数量最小化。该问题被称为“位删除谜题”。 以下是该问题的示例: 对于 n = 3 的情况,最优解是 2,对应两个不同的向量 11 和 00。对于 n = 6 的情况,最优解是 4。对于 n = 9 的情况,最优解是 6。对于 n = 12 的情况,最优解是 10。 对于较小的 n,这个问题可以通过

基于二进制正余弦算法的背包问题求解- 附代码

基于二进制正余弦算法的背包问题求解- 附代码 文章目录 基于二进制正余弦算法的背包问题求解- 附代码1.二进制正余弦算法2.背包问题3.实验结果4.参考文献5.Matlab 摘要:本文主要介绍二进制正余弦算法,并用其对背包问题进行求解。 1.二进制正余弦算法 正余弦优化算法是一种随机优化算法,具有高度的灵活性,原理简单,易于实现,可以方便地应用于不同领域的优化问题。正余弦

AcWing 1273:天才的记忆 ← ST算法求解RMQ问题

【题目来源】https://www.acwing.com/problem/content/1275/【题目描述】 从前有个人名叫 WNB,他有着天才般的记忆力,他珍藏了许多许多的宝藏。 在他离世之后留给后人一个难题(专门考验记忆力的啊!),如果谁能轻松回答出这个问题,便可以继承他的宝藏。 题目是这样的:给你一大串数字(编号为 1 到 N,大小可不一定哦!),在你看过一遍之后,它便消失在你面前,随后