斐波纳契数列(Fibonacci Sequence),又称黄金分割数列

#include <iostream>
#include <cmath>
using namespace std;

typedef unsigned int uint;

/**
* 斐波那契数列:1、1、2、3、5、8、13、21、……
 如果设F(n)为该数列的第n项(n∈N+)。那么这句话可以写成如下形式:
 F(1) = 1,F(2)=1,F(n)=F(n-1)+F(n-2) (n≥3),
 显然这是一个线性递推数列。

  斐波那契数列通项公式
  F(n)=(√5/5)*{[(1+√5)/2]^n - [(1-√5)/2]^n}(√5表示根号5)。
*/

uint fibonacci_seq_loop(uint n);
uint fibonacci_seq_noloop(uint n);

uint fibonacci_seq_loop(uint n)
{
    if (n==1 or n==2)
        return 1U;
    else
        return fibonacci_seq_loop(n-1)+fibonacci_seq_loop(n-2);
}

uint fiboncci_seq_noloop(uint n)
{
    //F(n) = F(n-1) + F(n-2) (n>=3)
    //F(1) = F(2) = 1

    uint nRet;  // F(n)
    uint nP;    // F(n-1)
    uint nPp;   // F(n-2)
    nRet = nP = nPp = 1U;

    if(n==1 or n==2)
        return nRet;
    for(size_t i = 3; i <= n; i++)
    {
        nRet = nP + nPp;
        nPp = nP;
        nP = nRet;
    }

    return nRet;
}

uint fibonacci_format(uint n)
{
    return (uint)(sqrt(5.0)/5*( pow((1+sqrt(5.0))/2, n) - pow((1-sqrt(5.0))/2, n) ));
}

int main()
{
    cout << "Fibonacci Sequence Generator" << endl;
    #if 10
    for(size_t n = 1; n < 100; n++)
        cout <<  n << '\t' << fiboncci_seq_noloop(n) << "\n";
    cout << endl;
    #endif

#if 0
    for(size_t i = 1; i < 100; i++)
        cout << i << '\t' << fibonacci_format(i) << '\n';
    cout << endl;
#endif
    return 0;
}

分析3:最后介绍一种效率最高的算法O(logn),首先我们有下面的数学公式:

我们可以用数学归纳法证明如下:

Step1: n=2时

Step2:设n=k时,公式成立,则有:

等式两边同乘以[1,1;1,0]矩阵可得:

左=右,这正是n=k+1时的形式,即当n=k+1时等式成立。

由Step1和Step2可知,该数学公式成立。

由此可以知道该问题转化为计算右边矩阵的n-1幂问题。

我们利用分治的算法思想可以考虑如下求解一个数A的幂。

实现这种算法需要定义矩阵,以及矩阵的有关运算,具体代码如下:

#include<iostream>
 #include<string>
 using namespace std;
 
 //定义2×2矩阵;
 struct Matrix2by2
 {
     //构造函数
     Matrix2by2
     (
         long m_00,
         long m_01,
         long m_10,
         long m_11
     )
     :m00(m_00),m01(m_01),m10(m_10),m11(m_11)
     {
     }
 
     //数据成员
     long m00;
     long m01;
     long m10;
     long m11;
 };
 
 //定义2×2矩阵的乘法运算
 Matrix2by2 MatrixMultiply(const Matrix2by2& matrix1,const Matrix2by2& matrix2)
 {
     Matrix2by2 matrix12(1,1,1,0);
     matrix12.m00 = matrix1.m00 * matrix2.m00 + matrix1.m01 * matrix2.m10;
     matrix12.m01 = matrix1.m00 * matrix2.m01 + matrix1.m01 * matrix2.m11;
     matrix12.m10 = matrix1.m10 * matrix2.m00 + matrix1.m11 * matrix2.m10;
     matrix12.m11 = matrix1.m10 * matrix2.m01 + matrix1.m11 * matrix2.m11;
     return matrix12;
 
 }
 
 
 //定义2×2矩阵的幂运算
 Matrix2by2 MatrixPower(unsigned int n)
 {
     Matrix2by2 matrix(1,1,1,0);
     if(n == 1)
     {
         matrix = Matrix2by2(1,1,1,0);
     }
     else if(n % 2 == 0)
     {
         matrix = MatrixPower(n / 2);
         matrix = MatrixMultiply(matrix, matrix);
     }
     else if(n % 2 == 1)
     {
         matrix = MatrixPower((n-1) / 2);
         matrix = MatrixMultiply(matrix, matrix);
         matrix = MatrixMultiply(matrix, Matrix2by2(1,1,1,0));
     }
     return matrix;
 }
 //计算Fibnacci的第n项
 long Fibonacci(unsigned int n)
 {
     if(n == 0)
         return 0;
     if(n == 1)
         return 1;
 
     Matrix2by2 fibMatrix = MatrixPower(n-1);
     return fibMatrix.m00;
     
 }
 
 int main()
 {
     cout<<"Enter A Number:"<<endl;
     unsigned int number;
     cin>>number;
     cout<<Fibonacci(number)<<endl;
     return 0;
 }

转载于:https://my.oschina.net/qihh/blog/93720

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值