多种方法求斐波那契数组,

来源:互联网 发布:用java编写小游戏视频 编辑:程序博客网 时间:2024/05/22 14:32

1.第一种方法是迭代,发现非常慢非常慢,大量重复计算,可见递归并不是什么高效的算法,我发现当求第50个的时候已经需要很长时间了,下面的代码测试的是计算第40个时间。

 

#include<iostream>#include"MyTimer.h"using namespace std; long long    conquer_fibonacci(long long A[],int n){ //递归法 很慢 很慢 ,大量的重复计算 可见递归并不是什么高效的算法 Ω(φ^n)    if(n==1){return A[n];}    else if(n!=2){        A[n]=conquer_fibonacci(A,n-1)+conquer_fibonacci(A,n-2);        return A[n];    }    else{        A[n]=A[0]+A[1];        return A[n];    }}int main(){ long long    fibonacci[40];fibonacci[0]=0;fibonacci[1]=1;int length=sizeof(fibonacci)/sizeof(long long );int a[]={1,1,1,0};MyTimer mt,mt2;mt.Start();  conquer_fibonacci(fibonacci,length-1); //递归求40个 , 保存在数组里mt.End();cout<<mt.costTime<<"us"<<endl;for(int i=0;i!=length;++i){    cout<<fibonacci[i]<<" ";if((i+1)%4==0)cout<<endl;}cout<<endl;return 0;
运行结果:


2.第二种就是 用普通的累加,运用前面计算的结果,是线性的,为了和第三中方法比较 我这里计算了第1001个的数据

#include<iostream>#include"MyTimer.h"using namespace std;int main(){unsigned long long fibonacci2[1001];fibonacci2[0]=0; fibonacci2[1]=1;int length=sizeof(fibonacci2)/sizeof(long long );MyTimer mt;mt.Start();for(int i=2;i!=length;++i){ //普通,从下而上 θ(n)    fibonacci2[i]=fibonacci2[i-1]+fibonacci2[i-2];}mt.End();cout<<mt.costTime<<"us"<<endl;cout<<fibonacci2[1000];cout<<endl;return 0;}

运行结果:


用时为3 us

3.第三章种就是用到斐波那契数组的一个特性


如上公式 要求Fn 只要求出矩阵

1 1

1 0

的n次方就可以得到Fn  。

然后用power number里的递归就可以在lgn 的时间内得到Fn

代码如下:

#include<iostream>#include"MyTimer.h"using namespace std;void recursive_square(unsigned long long a[],int n){    if(n==1){return;}   // 一次方 直接返回if((n%2)!=0){ //n为奇数    recursive_square(a,(n-1)/2);  //先求得(n-1)/2 的a矩阵的形态  unsigned long long   a0=a[0],a1=a[1],a2=a[2],a3=a[3];// 计算a的平方 ,a[0]=a0*a0+a1*a2;a[1]=a0*a1+a1*a3;a[2]=a2*a0+a3*a2;a[3]=a2*a1+a3*a3; a0=a[0];a1=a[1];a2=a[2];a3=a[3]; //再补乘一个 初始矩阵,,可以对照power number 只是这里用a来传导每次的结果a[0]=a0*1+a1*1;a[1]=a0*1+a1*0;a[2]=a2*1+a3*1;a[3]=a2*1+a3*0;}else{ //n为偶数 很简单 先得到n/2 的a的状态,再a平方就可以了int    mid =n/2;    recursive_square(a,mid);unsigned long long a0=a[0],a1=a[1],a2=a[2],a3=a[3];a[0]=a0*a0+a1*a2;a[1]=a0*a1+a1*a3;a[2]=a2*a0+a3*a2;a[3]=a2*a1+a3*a3;}}int main(){ unsigned long long  a[]={1,1,1,0}; //初始矩阵MyTimer mt;mt.Start();recursive_square(a,1000); //进入计算 初始矩阵的1000次方mt.End();cout<<endl;cout<<mt.costTime<<"us"<<endl;cout<<a[1]; //输出Fnreturn 0;}


运行结果:


可见计算结果是一样的 但是用时已经有细微差异了,如果计算更多 可以得到明显的差异。。


水平还是有限,这个递归完全自己写的,用了好久,相信会越来越好的。

0 0
原创粉丝点击