Una sequenza di Fibbonacci è quella che somma il risultato di un numero quando aggiunta al risultato precedente che inizia con 1.
so.. 1 + 1 = 2
2 + 3 = 5
3 + 5 = 8
5 + 8 = 13
8 + 13 = 21
Una volta capito cos'è Fibbonacci, possiamo iniziare a scomporre il codice.
public int fibonacci(int n) {
if(n == 0)
return 0;
else if(n == 1)
return 1;
else
return fibonacci(n - 1) + fibonacci(n - 2);
}
Il primo if statment verifica la presenza di un caso base, in cui il loop può interrompersi. L'altra dichiarazione if qui sotto sta facendo lo stesso, ma potrebbe essere riscritta in questo modo ...
public int fibonacci(int n) {
if(n < 2)
return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}
Ora che viene stabilito un caso base, dobbiamo capire lo stack di chiamate. La tua prima chiamata a "fibonacci" sarà l'ultima a risolversi nello stack (sequenza di chiamate) mentre si risolvono nell'ordine inverso da cui sono state chiamate. L'ultimo metodo chiamato si risolve per primo, quindi l'ultimo da chiamare prima di quello e così via ...
Quindi, tutte le chiamate vengono effettuate prima che qualsiasi cosa venga "calcolata" con tali risultati. Con un input di 8 prevediamo un output di 21 (vedere la tabella sopra).
fibonacci (n - 1) continua a essere chiamato fino a quando non raggiunge il case base, quindi fibonacci (n - 2) viene chiamato fino a quando non raggiunge il case base. Quando la pila inizia a sommare il risultato in ordine inverso, il risultato sarà così ...
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).
Continuano a gorgogliare (risolvendosi all'indietro) fino a quando la somma corretta non viene restituita alla prima chiamata nello stack ed è così che ottieni la tua risposta.
Detto questo, questo algoritmo è molto inefficiente perché calcola lo stesso risultato per ogni ramo in cui si divide il codice. Un approccio molto migliore è quello "dal basso verso l'alto" in cui non è richiesta Memoization (memorizzazione nella cache) o ricorsione (deep call stack).
Così...
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;
}