프로 그래 밍 의 아름다움 2.9: 신기 한 피 보 나치 수열
7189 단어 알고리즘
F(n)=⎧⎩⎨01F(n−1)+F(n−2)n = 0;n = 1;n>=2
보통 학교 에 서 는 재 귀 할 때 이 를 예 로 들 면 좋 지.면접 문제 도 이 문 제 를 볼 수 있 고 페 이 스 북 은 한 번 기대 고 있 었 다.하지만 재 귀적 으로 쓰 면 다음 면접 을 볼 필요 가 없다.이 유 는 하나 야, 너무 느 려!!반복 계산 이 너무 많아!!
보 세 요. F (5) 를 요구 하면 F (4) 와 F (3) 를 계산 하고 F (4) 를 계산 해 야 합 니 다. F (3) 를 다시 계산 해 야 합 니 다. 물론 느 립 니 다.그리고 함수 호출 은 스 택 포인터, 전달 매개 변수 등 을 저장 해 야 합 니 다.
좀 좋 은 사람 은 1 차원 배열 을 생각 할 수도 있 습 니 다.이렇게 하면 복잡 도 를 낮 출 수 있다.
O (n) 됐어, 나 도 여기 서 추 태 를 보 였 어.나의 실현 을 써 라.
스크롤 배열
#include <stdio.h>
int arr[3]={0,1};
int main(void){
int index=0;
printf("Enter the index:
");
scanf("%d",&index);
if(index<=2){
printf("%d
",arr[index-1]);
return 0;
}else{
for(int i=3;i<=index;++i){
arr[2]=arr[1]+arr[0];
arr[0]=arr[1];
arr[1]=arr[2];
}
}
printf("%d
",arr[2]);
return 0;
}
자, 이것 이 바로 전설의 복잡 도가 O (N) 인 방법 입 니 다. 예전 의 재 귀 보다 좋 습 니 다.면접 때 이 걸 쓰 는 것 도 평균 수준 에 이 를 뻔 했다.이론 적 으로 는 가능 하지만 다음 방법 도 있다.수열 을 구 하 는 통항 공식 이지 만 이 는 무리 수 를 도입 했다.그래서 사실은 안 돼.다음은 가장 난폭 하고 수준 있 는 방법 이다.복잡 도 는 O (Log2N) 에 도달 할 수 있다. 전략 은 당연히 내 가 베 낀 것 이다.행렬 을 쓰다.피 보 나치 가 2 단계 푸 시 수열 이기 때문에 행렬 에 걸 맞 은 공식 으로 얻 을 수 있다.2 * 2 의 행렬 A 가 존재 한다.이로써 (FnFn - 1) = (Fn - 1Fn - 2) ∗ A 구 해 를 얻 을 수 있다.
A=(1110)
위 에서 내 놓 을 수 있 습 니 다:
(FnFn−1)=(Fn−1Fn−2)∗A=(Fn−2Fn−3)∗A2=....=(F1F0)An−1
봤 어, 지금 은 구 할 수 있 기만 하면 돼.
An - 1, 그리고 행렬 곱셈 을 하면 됩 니 다.
그래서 우리 가 해 야 할 일 은 행렬 작업 의 클래스 나 함 수 를 실현 하 는 것 이다.OK, 나 는 B 를 담 고 간단 한 실현 을 쓰 고 있다.
#include <iostream>
#include <cassert>
using namespace std;
const int N=4;
class Martix{
public:
unsigned int size;
long long int data[N*N];
};
//Multi bewteen martix and martix
Martix martixMulti(const Martix A,const Martix B,Martix result){
assert(A.size==B.size);
result.size=A.size;
for(int i=0;i<result.size;++i)
for(int j=0;j<result.size;++j){
result.data[i*result.size+j]=0;
for(int k=0;k<result.size;++k)
result.data[i*result.size+j]+=A.data[i*A.size+k]*B.data[k*B.size+j];
}
return result;
}
//Compute the n-1 of exp
Martix martixPow(Martix &A,int index){
if(index==0)
exit(0);
--index; //compute n-1 exp
Martix IdenMartix;
IdenMartix.size=2;
IdenMartix.data[0]=1,IdenMartix.data[1]=0;
IdenMartix.data[2]=0,IdenMartix.data[3]=1;
Martix result=IdenMartix;
for(;index;index>>=1){
if(index&1)
result=martixMulti(result,A,result);
A=martixMulti(A,A,A);
}
return result;
}
int Fib(int n){
Martix A;
A.size=2;
A.data[0]=1,A.data[1]=1;
A.data[2]=1,A.data[3]=0;
Martix an=martixPow(A,n);
return an.data[0];
}
int main(int agrc,char **argv){
unsigned int index;
cout<<"Input index:";cin>>index;
cout<<Fib(index)<<endl;
return 0;
}
상술 한 것 은 간단 한 실현 이지 만 코드 에 약간의 문제 가 있다.하, 너희들 스스로 알 아서 해라.다음 글 은 대수 계산 을 쓸 것 으로 추정 된다.마침 그 계약 수열 의 항수 가 너무 많 을 때 표시 할 수 없 는 상황 이 었 다.참고 자료: < 프로 그래 밍 의 아름다움 > 서적 프로 그래 밍 의 아름다움 2.9
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
【Codility Lesson3】FrogJmpA small frog wants to get to the other side of the road. The frog is currently located at position X and wants to get to...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.