斐波那契数列的多种解法
斐波那契函数的定义:斐波那契数列,又称黄金分割数列,指的是这样一个数列:0、1、1、2、3、5、8、13、21、34、……在数学上,斐波纳契数列以如下被以递归的方法定义:F(0)=0,F(1)=1,F(n)=F(n-1)+F(n-2)(n≥2,n∈N*)
解法一
利用递归的方法做
首先要确定递归的终止条件:F(0)=1,F(1)=1。只后再利用公式F(n)=F(n-1)+F(n-2)(n≥2,n∈N*)即可
#include<stdio.h>
int f(int n)
{
//递归终止条件
if(n==0) return 0;
if(n==1) return 1;
//递归函数
return (f(n-1)+f(n-2));
}
int main()
{
int n;
scanf("%d",&n);
printf("%d\n",f(n));
return 0;
}
但是经过仔细的思考发现,该递过在运行过程中会出现许多重复计算的现象,利于计算F(4)时就要算边F(2).那么有什么办法可以改善一下吗。下面我们通过添加一个数组来解决这个问题。
#include<stdio.h>
int a[100]={0};
int f(int n)
{
//递归终止条件
if(n==0) return 0;
//如果已经计算过就不用再次计算了
if(a[n]!=0) return a[n];
//记录下斐波那契数列的值避免重复的计算
a[n]=f(n-1)+f(n-2);
return a[n];
}
int main()
{
a[1]=1;
int n;
scanf("%d",&n);
printf("%d\n",f(n));
return 0;
}
解法二
利用循环实现
#include<stdio.h>
int a[100]={0};
int f(int n)
{
int first=0,second=1,third;
if(n==0) return 0;
if(n==1) return 1;
while(n!=1){
third=first+second;
first=second;
second=third;
n--;
}
return third;
}
int main()
{
a[1]=1;
int n;
scanf("%d",&n);
printf("%d\n",f(n));
return 0;
}
解法三
利用矩阵快速幂实现
在写代码之前我们先来了解什么是矩阵快速幂
先来看看这样一个问题如果让你求解x6的话你会怎么算呢是不是直接写成xxxxx*x呢?显然这样的话要做五次关于x的乘法。有没有一种方法可以减少运算的次数呢。
首先我们把6写成二进制的形式110则x6=x4*x2.而x4=x2*x2。我们这样我们仅仅只需要做3次乘法就可以计算出x6的值。进一步我们将之代码化如下
#include<stdio.h>
int f(int x,int e)
{
int result=1;
while(e!=0)
{
if(e&1){
result*=x;
}
x*=x;
e>>=1;
}
return result;
}
int main()
{
int x,e;
printf("请输入底数和指数:");
scanf("%d %d",&x,&e);
printf("%d",f(x,e));
}
那么同样的假设A为一个矩阵那么An是否可是用同样的方法来计算呢,大家可以在私下里试一试。只需要在添加一个用于计算矩阵相乘的函数就可以了。
那么该如何利用这个方法来计算斐波那契数列呢,请看下面的公式。
f[i] = 1f[i-1]+1f[i-2] f[i-1] = 1f[i-1] + 0f[i-2];
即
那么可以得到
就这两幅图完美诠释了斐波那契数列如何用矩阵来实现。
那么下面看下代码的实现
#include<stdio.h>
typedef struct
{
long long b[2][2];
}X;
X mul(X a,X b,int an,int bn,int abk)
{
X tem;
int i,j,k;
for(i=0;i<an;i++){
for(j=0;j<bn;j++){
tem.b[i][j]=0;
}
}
for(i=0;i<an;i++){
for(j=0;j<bn;j++){
for(k=0;k<abk;k++){
tem.b[i][j]=(a.b[i][k]*b.b[k][j]+tem.b[i][j]);
}
}
}
return tem;
}
long long fibornacci(long long n)
{
if(n==1) return 1;
//初始化矩阵
X res;
res.b[0][0]=1;
res.b[0][1]=1;
res.b[1][0]=1;
res.b[1][1]=0;
//用于存放答案的矩阵
X ans;
ans.b[0][0]=1;
ans.b[0][1]=1;
ans.b[1][0]=1;
ans.b[1][1]=1;
n=n-2;
while(n){
if(n&1){
ans=mul(ans,res,2,2,2);
}
res=mul(res,res,2,2,2);
n>>=1;
}
X y;
y.b[0][0]=1;
y.b[1][0]=0;
ans=mul(ans,y,2,1,2);
return ans.b[0][0];
}
int main()
{
long long n;
scanf("%lld",&n);
printf("%lld\n",fibornacci(n));
return 0;
}
好了以上便是关于斐波那契函数的几种解法,看都看都这里了确定不点一个赞,加一个关注吗。QAQ