피보나치 수열은 1로 시작하는 이전 결과에 추가 될 때 수의 결과를 합한 것입니다.
so.. 1 + 1 = 2
2 + 3 = 5
3 + 5 = 8
5 + 8 = 13
8 + 13 = 21
피보나치가 무엇인지 이해하면 코드를 분석하기 시작할 수 있습니다.
public int fibonacci(int n) {
if(n == 0)
return 0;
else if(n == 1)
return 1;
else
return fibonacci(n - 1) + fibonacci(n - 2);
}
첫 번째 if 문은 루프가 발생할 수있는 기본 사례를 확인합니다. 아래의 else if 문은 동일하지만 다시 작성 될 수 있습니다 ...
public int fibonacci(int n) {
if(n < 2)
return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}
이제 기본 사례가 확립되었으므로 호출 스택을 이해해야합니다. "fibonacci"에 대한 첫 번째 호출은 호출 된 순서와 반대 순서로 해결 될 때 스택 (통화 순서)에서 마지막으로 해결됩니다. 마지막으로 호출 된 메소드가 먼저 해결 된 다음 마지막으로 호출되기 전에 마지막으로 호출됩니다.
따라서 모든 결과는 해당 결과로 "계산"되기 전에 먼저 이루어집니다. 입력이 8이면 21이 출력됩니다 (위 표 참조).
피보나치 (n-1)는 기본 사례에 도달 할 때까지 계속 호출되고, 피보나치 (n-2)는 기본 사례에 도달 할 때까지 호출됩니다. 스택이 결과를 역순으로 합치기 시작하면 결과는 다음과 같습니다.
1 + 1 = 1 ---- last call of the stack (hits a base case).
2 + 1 = 3 ---- Next level of the stack (resolving backwards).
2 + 3 = 5 ---- Next level of the stack (continuing to resolve).
올바른 합계가 스택의 첫 번째 호출로 반환 될 때까지 버블 링을 계속합니다 (거꾸로 해결). 그렇게하면 답변을 얻는 방법입니다.
이 알고리즘은 코드가 분할되는 각 분기에 대해 동일한 결과를 계산하기 때문에 매우 비효율적입니다. 훨씬 더 나은 방법은 메모 (캐싱) 또는 재귀 (딥 콜 스택)가 필요없는 "하단"방법입니다.
이렇게 ...
static int BottomUpFib(int current)
{
if (current < 2) return current;
int fib = 1;
int last = 1;
for (int i = 2; i < current; i++)
{
int temp = fib;
fib += last;
last = temp;
}
return fib;
}