// 也谈斐波那契数列.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; }