// 也谈斐波那契数列.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <exception>
#include <iostream>
using namespace std;
/********************************************
设计者:cslave
版本说明:本代码免费用于商用,拷贝,转移,使用,但是
有本代码导致的问题,本人概不负责。
设计时间:2012.6.25
分发原则:遵守GNU规范。
题目:写一个函数,输入n,求斐波那契数列的第n项,斐波那契
数列的定义如下:
| 0 n=0
f(n)= | 1 n=1
| f(n-1)+f(n-2) n>1
由三种方法
方法1:纯递归
方法2:迭代 效率相对高效,避免了很多子问题的重复计算
方法3:O(lg(n))量级的算法。
********************************************/
struct Matrix //定义矩阵
{
int M11;
int M12;
int M21;
int M22;
};
Matrix M2={1,1,1,0};
long long FibonacciRcur( int n) //这个方法虽然简单,但值得一提的是很多人都写错了,包括何海涛老师,这里必须是
{ //这里n必须是int 不能是unsigned int,如果是unsigned int 则递归无法退出。
if(n<0)
return 0;
if(n==1)
return 1;
return FibonacciRcur(n-1)+FibonacciRcur(n-2);
}
long long FibonacciIter( int n)
{
int Result[2]={0,1};
if(n<2)
return Result[n];
long long fibNMinusOne=1;
long long fibNMinusTwo=0;
long long fibNMinusN=0;
for(int i=2;i<=n;++i)
{
fibNMinusN=fibNMinusOne+fibNMinusTwo;
fibNMinusTwo=fibNMinusOne;
fibNMinusOne=fibNMinusN;
}
return fibNMinusN;
}
Matrix* MatrixMultiply(const Matrix* arr,const Matrix* brr) // 模拟矩阵乘法 不算高校,可以采用引用接口
{
Matrix* c=(Matrix *)malloc(sizeof(Matrix));
c->M11=arr->M11*brr->M11+arr->M12*brr->M21;
c->M12=arr->M11*brr->M12+arr->M12*brr->M22;
c->M21=arr->M21*brr->M11+arr->M22*brr->M21;
c->M22=arr->M21*brr->M12+arr->M22*brr->M22;
return c;
}
Matrix* FibonacciMatrix(unsigned int n) // |f(n) f(n-1)|=a^(n-1) 其中a= | 1 1 |
{ // | f(n-1) f(n-2)| | 1 0 |
if(n==1)
return &M2;
if(n==2)
return MatrixMultiply(&M2,&M2); //本函数即为求a^n的函数
Matrix *M=(Matrix *)malloc(sizeof(Matrix));
M=FibonacciMatrix(n>>1);
M=MatrixMultiply(M,M);
if((n & (1))==1)
M=MatrixMultiply(M,&M2);
return M;
}
void Test()
{
int n;
cout<<"请输入斐波那契数: "<<endl;
cin>>n;
long long aim=0;
Matrix *M=(Matrix *)malloc(sizeof(Matrix));
try
{
if(n<3)
throw exception("Invalid Input!");
cout<<"递归的斐波那契被调用!:";
aim=FibonacciRcur(n);
cout<<aim<<endl;
cout<<"迭代的斐波那契被调用!:";
aim=FibonacciIter(n);
cout<<aim<<endl;
cout<<"O(lg(n))的斐波那契调用!:";
M=FibonacciMatrix(--n);
cout<<M->M11<<endl;
}
catch(exception& exception)
{
cout<<"You Input In valid Input!"<<endl;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
Test();
return 0;
}