>  기사  >  백엔드 개발  >  피보나치 수열의 일반항을 구현하는 7가지 방법

피보나치 수열의 일반항을 구현하는 7가지 방법

高洛峰
高洛峰원래의
2017-01-14 16:41:341657검색

1: 재귀 구현
f[n]=f[n-1]+f[n-2] 공식을 사용하고, 재귀 종료 조건은 f[1]=1입니다. f[2] =1.
두 번째: 배열 구현
공간 복잡도와 시간 복잡도는 모두 0(n)이고 효율성은 평균이며 재귀보다 빠릅니다.
셋: 벡터 구현
시간 복잡도는 0(n)이고, 시간 복잡도는 0(1)입니다. 물론 벡터가 효율적인지는 알 수 없습니다. 자원을 차지할 자체 속성입니다.
4: Queue 구현
물론 배열보다 피보나치 수열을 구현하는 데에는 대기열이 더 적합합니다. 시간 복잡도와 공간 복잡도는 Vector와 동일하지만, 여기에는 대기열이 적합합니다. 🎜> f(n)=f(n-1)+f(n-2), f(n)은 f(n-1) 및 f(n-2)에만 관련됩니다. f(n)이 큐, f(n-2)는 큐에서 제거될 수 있습니다.
다섯 번째: 반복 구현
반복 구현은 시간 복잡도가 0(n)이고 공간 복잡도가 0(1)인 가장 효율적입니다.
식스: 수식 구현
바이두를 검색하다가 피보나치수열에 수식이 있어서 그 수식을 이용해서 계산할 수 있다는 걸 알게 됐어요.
double형의 정확도가 충분하지 않기 때문에 프로그램에서 계산한 결과에 오류가 발생합니다. 수식을 확장하여 계산하면 결과가 정확해집니다.
완전한 구현 코드는 다음과 같습니다.

#include "iostream"
#include "queue"
#include "cmath"
using namespace std;
int fib1(int index)     //递归实现
{
 if(index<1)
 {
  return -1;
 }
 if(index==1 || index==2)
  return 1;
 return fib1(index-1)+fib1(index-2);
}
int fib2(int index)     //数组实现
{
 if(index<1)
 {
  return -1;
 }
 if(index<3)
 {
  return 1;
 }
 int *a=new int[index];
 a[0]=a[1]=1;
 for(int i=2;i<index;i++)
  a[i]=a[i-1]+a[i-2];
 int m=a[index-1];
 delete a;         //释放内存空间
 return m;
}
int fib3(int index)           //借用vector<int>实现
{
 if(index<1)
 {
  return -1;
 }
 vector<int> a(2,1);      //创建一个含有2个元素都为1的向量
 a.reserve(3);
 for(int i=2;i<index;i++)
 {
  a.insert(a.begin(),a.at(0)+a.at(1));
  a.pop_back();
 }
 return a.at(0);
} 
int fib4(int index)       //队列实现
{
 if(index<1)
 {
  return -1;
 }
 queue<int>q;
 q.push(1);
 q.push(1);
 for(int i=2;i<index;i++)
 {
  q.push(q.front()+q.back());
  q.pop();
 }
 return q.back();
}
int fib5(int n)          //迭代实现
{
 int i,a=1,b=1,c=1;
 if(n<1)
 {
  return -1;
 }
 for(i=2;i<n;i++)
 {
  c=a+b;     //辗转相加法(类似于求最大公约数的辗转相除法)
  a=b;
  b=c;
 }
 return c;
}
int fib6(int n)
{
 double gh5=sqrt((double)5);
 return (pow((1+gh5),n)-pow((1-gh5),n))/(pow((double)2,n)*gh5);
} 
int main(void)
{
 printf("%d\n",fib3(6));
 system("pause");
 return 0;
}

Seven: Bipartite Matrix Method

피보나치 수열의 일반항을 구현하는 7가지 방법

위에 표시된 것처럼 피보나치 수열의 모든 항목은 다음과 같습니다. 행렬 거듭제곱을 사용하여 계산되며 n번째 거듭제곱은 로그 시간에 계산될 수 있습니다.

코드는 아래와 같습니다:

void multiply(int c[2][2],int a[2][2],int b[2][2],int mod)
{
 int tmp[4];
 tmp[0]=a[0][0]*b[0][0]+a[0][1]*b[1][0];
 tmp[1]=a[0][0]*b[0][1]+a[0][1]*b[1][1];
 tmp[2]=a[1][0]*b[0][0]+a[1][1]*b[1][0];
 tmp[3]=a[1][0]*b[0][1]+a[1][1]*b[1][1];
 c[0][0]=tmp[0]%mod;
 c[0][1]=tmp[1]%mod;
 c[1][0]=tmp[2]%mod;
 c[1][1]=tmp[3]%mod;
}//计算矩阵乘法,c=a*b
int fibonacci(int n,int mod)//mod表示数字太大时需要模的数
{
 if(n==0)return 0;
 else if(n<=2)return 1;//这里表示第0项为0,第1,2项为1
 int a[2][2]={{1,1},{1,0}};
 int result[2][2]={{1,0},{0,1}};//初始化为单位矩阵
 int s;
 n-=2;
 while(n>0)
 {
  if(n%2 == 1)
   multiply(result,result,a,mod);
  multiply(a,a,a,mod);
  n /= 2;
 }//二分法求矩阵幂
 s=(result[0][0]+result[0][1])%mod;//结果
 return s;
}

첨부된 것은 a의 n차 거듭제곱 함수를 계산하는 이분법입니다.

int pow(int a,int n)
{
 int ans=1;
 while(n)
 {
  if(n&1)
   ans*=a;
  a*=a;
  n>>=1;
 }
 return ans;
}

피보나치 수열의 일반항을 찾는 7가지 구현 방법에 대한 더 많은 관련 기사를 보려면 PHP 중국어 웹사이트를 주목하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.