海涛老师的面试题作业9也谈斐波那契数列

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

  

原文地址:https://www.cnblogs.com/cslave/p/2565780.html