Sequenza di Fibonacci ricorsiva Java


156

Per favore, spiega questo semplice 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);
}

Sono confuso con l'ultima riga soprattutto perché se n = 5 per esempio, allora verrebbero chiamati fibonacci (4) + fibonacci (3) e così via, ma non capisco come questo algoritmo calcoli il valore all'indice 5 da questo metodo. Per favore, spiega con molti dettagli!


8
Si noti che questo è ricorsivo e viene eseguito in tempo esponenziale. È inefficiente per grandi valori di N. Utilizzando un approccio iterativo sono stato in grado di calcolare i primi 10.000 numeri nella sequenza. Possono essere trovati qui - goo.gl/hnbF5
Adam

@AdamFisher: puoi per favore condividere il codice che hai usato per calcolare 10.000 numeri in sequenza? In realtà sono curioso di saperlo.
Shumail,

4
@AdamFisher Il link a cui hai fatto riferimento è morto.
iRuth,

2
Questo video spiegherà come comprendere la funzione ricorsiva in 10 minuti youtube.com/watch?v=t4MSwiqfLaY
Chathura Palihakkara

2
C'è anche un approccio iterativo che potrebbe essere meno difficile per te. Grande articolo su Ricorsivo e Iterativo con codice qui - codeflex.co/java-get-fibonacci-number-by-index
user5495300

Risposte:


165

Nella sequenza fibonacci ogni elemento è la somma dei due precedenti. Quindi, hai scritto un algoritmo ricorsivo.

Così,

fibonacci(5) = fibonacci(4) + fibonacci(3)

fibonacci(3) = fibonacci(2) + fibonacci(1)

fibonacci(4) = fibonacci(3) + fibonacci(2)

fibonacci(2) = fibonacci(1) + fibonacci(0)

Adesso lo sai già fibonacci(1)==1 and fibonacci(0) == 0 . Quindi, puoi successivamente calcolare gli altri valori.

Adesso,

fibonacci(2) = 1+0 = 1
fibonacci(3) = 1+1 = 2
fibonacci(4) = 2+1 = 3
fibonacci(5) = 3+2 = 5

E dalla sequenza fibonacci 0,1,1,2,3,5,8,13,21....possiamo vedere che per 5th elementla sequenza fibonacci ritorna 5.

Vedi qui per il tutorial sulla ricorsione .


funzionerà ma non sarà ottimizzato fino a quando non sarà ottimizzato. Dai un'occhiata alla mia risposta. Fammi sapere in caso di suggerimenti / commenti
M Sach

52

Ci sono 2 problemi con il tuo codice:

  1. Il risultato è memorizzato in int che può gestire solo i primi 48 numeri di fibonacci, dopodiché il numero intero riempie meno il bit e il risultato è errato.
  2. Ma non puoi mai eseguire fibonacci (50).
    Il codice
    fibonacci(n - 1) + fibonacci(n - 2)
    è molto sbagliato.
    Il problema è che chiama fibonacci non 50 volte ma molto di più.
    Inizialmente chiama fibonacci (49) + fibonacci (48),
    successivamente fibonacci (48) + fibonacci (47) e fibonacci (47) + fibonacci (46)
    Ogni volta peggiorava il fibonacci (n), quindi la complessità è esponenziale. inserisci qui la descrizione dell'immagine

L'approccio al codice non ricorsivo:

 double fibbonaci(int n){
    double prev=0d, next=1d, result=0d;
    for (int i = 0; i < n; i++) {
        result=prev+next;
        prev=next;
        next=result;
    }
    return result;
}

4
Sebbene alcune delle altre risposte spieghino più chiaramente la ricorsione, questa è probabilmente la risposta più pertinente a un livello più profondo.
Hal50000,

1
Che cosa significa "riempimento intero meno bit"?
Richard

1
@richard, si tratta di come viene memorizzato il numero intero. Dopo che int ha raggiunto 2 ^ 31-1, il bit successivo riguarda il segno, quindi il numero diventa negativo.
chro

Molto più veloce quindi ricorsivo. L'unica riserva è che non funzionerà per n = 1. Sono necessarie condizioni aggiuntive
v0rin

1
"Ogni volta che è peggiorato di 2 ^ n" in realtà è il numero di chiamate di funzioni totali 2*fibonacci(n+1)-1, quindi cresce con la stessa complessità dei numeri di fibonacci stessi, che è 1.618 ^ n invece di 2 ^ n
Aemyl,

37

Nello pseudo codice, dove n = 5, si verifica quanto segue:

fibonacci (4) + fibonnacci (3)

Questo si scompone in:

(fibonacci (3) + fibonnacci (2)) + (fibonacci (2) + fibonnacci (1))

Questo si scompone in:

(((fibonacci (2) + fibonnacci (1)) + ((fibonacci (1) + fibonnacci (0))) + ((((fibonacci (1) + fibonnacci (0)) + 1))

Questo si scompone in:

((((fibonacci (1) + fibonnacci (0)) + 1) + ((1 + 0)) + ((1 + 0) + 1))

Questo si scompone in:

((((1 + 0) + 1) + ((1 + 0)) + ((1 + 0) + 1))

Ciò si traduce in: 5

Dato che la sequenza fibonnacci è 1 1 2 3 5 8 ... , il 5 ° elemento è 5. Puoi usare la stessa metodologia per capire le altre iterazioni.


Penso che questa risposta spieghi le domande nel modo migliore. Davvero semplice
Tra il

Questo è pulito. Spiega sia il valore all'ennesimo termine sia la serie che segue.
Punto

12

La ricorsione può essere difficile da comprendere a volte. Basta valutarlo su un pezzo di carta per un piccolo numero:

fib(4)
-> fib(3) + fib(2)
-> fib(2) + fib(1) + fib(1) + fib(0)
-> fib(1) + fib(0) + fib(1) + fib(1) + fib(0)
-> 1 + 0 + 1 + 1 + 0
-> 3

Non sono sicuro di come Java lo valuti, ma il risultato sarà lo stesso.


sulla seconda riga da dove provengono 1 e 0 alla fine?
pocockn,

1
@pocockn fib (2) = fib (1) + fib (0)
tim

Quindi hai fib (4) quindi n-1 e n-2 sarebbero fib (3) + fib (2), quindi fai di nuovo n-1 e n-2 che ottieni -> fib (2) + fib (1 ), da dove hai preso + fib (1) + fib (0)? Aggiunto alla fine
pocockn

@pocockn fib (2) + fib (1) è di fib (3), fib (1) + fib (0) è di fib (2)
tim

12

Puoi anche semplificare la tua funzione, come segue:

public int fibonacci(int n)  {
    if (n < 2) return n;

    return fibonacci(n - 1) + fibonacci(n - 2);
}

In che modo è diverso da questo o questo o questa risposta?
Tunaki,

6
È solo più breve e più facile da leggere, quali algoritmi dovrebbero essere sempre =)
Otavio Ferreira,

@OtavioFerreira l'unica risposta che è riuscita a risolvere il mio problema, buon lavoro
KKKKK

8
                                F(n)
                                /    \
                            F(n-1)   F(n-2)
                            /   \     /      \
                        F(n-2) F(n-3) F(n-3)  F(n-4)
                       /    \
                     F(n-3) F(n-4)

Un punto importante da notare è che questo algoritmo è esponenziale perché non memorizza il risultato di precedenti numeri calcolati. es. F (n-3) viene chiamato 3 volte.

Per maggiori dettagli consultare l'algoritmo di dasgupta capitolo 0.2


Esiste una metodologia di programmazione in base alla quale possiamo evitare di calcolare F (n) per lo stesso n ancora e ancora utilizzando la Programmazione dinamica
Amit_Hora

8

La maggior parte delle risposte sono buone e spiega come funziona la ricorsione nei fibonacci.

Ecco un'analisi delle tre tecniche che include anche la ricorsione:

  1. Per Loop
  2. ricorsione
  3. Memoizzazione

Ecco il mio codice per testare tutti e tre:

public class Fibonnaci {
    // Output = 0 1 1 2 3 5 8 13

    static int fibMemo[];

    public static void main(String args[]) {
        int num = 20;

        System.out.println("By For Loop");
        Long startTimeForLoop = System.nanoTime();
        // returns the fib series
        int fibSeries[] = fib(num);
        for (int i = 0; i < fibSeries.length; i++) {
            System.out.print(" " + fibSeries[i] + " ");
        }
        Long stopTimeForLoop = System.nanoTime();
        System.out.println("");
        System.out.println("For Loop Time:" + (stopTimeForLoop - startTimeForLoop));


        System.out.println("By Using Recursion");
        Long startTimeRecursion = System.nanoTime();
        // uses recursion
        int fibSeriesRec[] = fibByRec(num);

        for (int i = 0; i < fibSeriesRec.length; i++) {
            System.out.print(" " + fibSeriesRec[i] + " ");
        }
        Long stopTimeRecursion = System.nanoTime();
        System.out.println("");
        System.out.println("Recursion Time:" + (stopTimeRecursion -startTimeRecursion));



        System.out.println("By Using Memoization Technique");
        Long startTimeMemo = System.nanoTime();
        // uses memoization
        fibMemo = new int[num];
        fibByRecMemo(num-1);
        for (int i = 0; i < fibMemo.length; i++) {
            System.out.print(" " + fibMemo[i] + " ");
        }
        Long stopTimeMemo = System.nanoTime();
        System.out.println("");
        System.out.println("Memoization Time:" + (stopTimeMemo - startTimeMemo));

    }


    //fib by memoization

    public static int fibByRecMemo(int num){

        if(num == 0){
            fibMemo[0] = 0;
            return 0;
        }

        if(num ==1 || num ==2){
          fibMemo[num] = 1;
          return 1; 
        }

        if(fibMemo[num] == 0){
            fibMemo[num] = fibByRecMemo(num-1) + fibByRecMemo(num -2);
            return fibMemo[num];
        }else{
            return fibMemo[num];
        }

    }


    public static int[] fibByRec(int num) {
        int fib[] = new int[num];

        for (int i = 0; i < num; i++) {
            fib[i] = fibRec(i);
        }

        return fib;
    }

    public static int fibRec(int num) {
        if (num == 0) {
            return 0;
        } else if (num == 1 || num == 2) {
            return 1;
        } else {
            return fibRec(num - 1) + fibRec(num - 2);
        }
    }

    public static int[] fib(int num) {
        int fibSum[] = new int[num];
        for (int i = 0; i < num; i++) {
            if (i == 0) {
                fibSum[i] = i;
                continue;
            }

            if (i == 1 || i == 2) {
                fibSum[i] = 1;
                continue;
            }

            fibSum[i] = fibSum[i - 1] + fibSum[i - 2];

        }
        return fibSum;
    }

}

Ecco i risultati:

By For Loop
 0  1  1  2  3  5  8  13  21  34  55  89  144  233  377  610  987  1597  2584  4181 
For Loop Time:347688
By Using Recursion
 0  1  1  2  3  5  8  13  21  34  55  89  144  233  377  610  987  1597  2584  4181 
Recursion Time:767004
By Using Memoization Technique
 0  1  1  2  3  5  8  13  21  34  55  89  144  233  377  610  987  1597  2584  4181 
Memoization Time:327031

Quindi possiamo vedere che la memoizzazione è il momento migliore per quanto riguarda e per le partite in loop da vicino.

Ma la ricorsione richiede più tempo e potresti essere che dovresti evitare nella vita reale. Inoltre, se stai utilizzando la ricorsione, assicurati di ottimizzare la soluzione.


1
"Qui possiamo vedere che il loop è il momento migliore"; "Per Loop Time: 347688"; "Tempo di memorizzazione: 327031"; 347688> 327031.
AjahnCharles l'

@CodeConfident Sì, ho visto quell'errore oggi e stavo per correggerlo. Grazie comunque :).
Pritam Banerjee,

7

Questo è il miglior video che ho trovato che spiega pienamente la ricorsione e la sequenza di Fibonacci in Java.

http://www.youtube.com/watch?v=dsmBRUCzS7k

Questo è il suo codice per la sequenza e la sua spiegazione è migliore di quanto potrei mai fare cercando di scriverlo.

public static void main(String[] args)
{
    int index = 0;
    while (true)
    {
        System.out.println(fibonacci(index));
        index++;
    }
}
    public static long fibonacci (int i)
    {
        if (i == 0) return 0;
        if (i<= 2) return 1;

        long fibTerm = fibonacci(i - 1) + fibonacci(i - 2);
        return fibTerm;
    }

5

Per la soluzione ricorsiva dei fibonacci, è importante salvare l'output di numeri di fibonacci più piccoli, mentre si recupera il valore di un numero maggiore. Questo si chiama "Memoizing".

Ecco un codice che utilizza la memorizzazione dei valori di fibonacci più piccoli, mentre recupera un numero di fibonacci più grande. Questo codice è efficiente e non effettua più richieste della stessa funzione.

import java.util.HashMap;

public class Fibonacci {
  private HashMap<Integer, Integer> map;
  public Fibonacci() {
    map = new HashMap<>();
  }
  public int findFibonacciValue(int number) {
    if (number == 0 || number == 1) {
      return number;
    }
    else if (map.containsKey(number)) {
      return map.get(number);
    }
    else {
      int fibonacciValue = findFibonacciValue(number - 2) + findFibonacciValue(number - 1);
      map.put(number, fibonacciValue);
      return fibonacciValue;
    }
  }
}

4

nella sequenza fibonacci , i primi due elementi sono 0 e 1, ogni altro elemento è la somma dei due elementi precedenti. cioè:
0 1 1 2 3 5 8 ...

quindi il 5 ° oggetto è la somma del 4 ° e del 3 ° elemento.


4

Michael Goodrich e altri forniscono un algoritmo davvero intelligente in Strutture di dati e algoritmi in Java, per risolvere i fibonacci in modo ricorsivo nel tempo lineare restituendo una matrice di [fib (n), fib (n-1)].

public static long[] fibGood(int n) {
    if (n < = 1) {
        long[] answer = {n,0};
        return answer;
    } else {
        long[] tmp = fibGood(n-1);
        long[] answer = {tmp[0] + tmp[1], tmp[0]};
        return answer;
    }
}

Questo produce fib (n) = fibGood (n) [0].


4

Ecco la soluzione O (1):

 private static long fibonacci(int n) {
    double pha = pow(1 + sqrt(5), n);
    double phb = pow(1 - sqrt(5), n);
    double div = pow(2, n) * sqrt(5);

    return (long) ((pha - phb) / div);
}

Formula del numero di Fibonacci di Binet utilizzata per l'implementazione di cui sopra. Per ingressi di grandi dimensioni longpuò essere sostituito con BigDecimal.


3

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;
        }

2

La maggior parte delle soluzioni qui offerte funziona in complessità O (2 ^ n). Il ricalcolo di nodi identici nell'albero ricorsivo è inefficiente e spreca cicli di CPU.

Possiamo usare la memoizzazione per far funzionare la funzione fibonacci in tempo O (n)

public static int fibonacci(int n) {
    return fibonacci(n, new int[n + 1]);
}

public static int fibonacci(int i, int[] memo) {

    if (i == 0 || i == 1) {
        return i;
    }

    if (memo[i] == 0) {
        memo[i] = fibonacci(i - 1, memo) + fibonacci(i - 2, memo);
    }
    return memo[i];
}

Se seguiamo il percorso di programmazione dinamica Bottom-Up, il codice seguente è abbastanza semplice da calcolare i fibonacci:

public static int fibonacci1(int n) {
    if (n == 0) {
        return n;
    } else if (n == 1) {
        return n;
    }
    final int[] memo = new int[n];

    memo[0] = 0;
    memo[1] = 1;

    for (int i = 2; i < n; i++) {
        memo[i] = memo[i - 1] + memo[i - 2];
    }
    return memo[n - 1] + memo[n - 2];
}

2

Perché questa risposta è diversa

Ogni altra risposta o:

  • Stampa invece di resi
  • Esegue 2 chiamate ricorsive per iterazione
  • Ignora la domanda utilizzando i loop

(a parte: nessuno di questi è effettivamente efficace; usa la formula di Binet per calcolare direttamente l' ennesimo termine)

Fibra ricorsiva della coda

Ecco un approccio ricorsivo che evita una chiamata doppia ricorsiva passando sia la risposta precedente che quella precedente.

private static final int FIB_0 = 0;
private static final int FIB_1 = 1;

private int calcFibonacci(final int target) {
    if (target == 0) { return FIB_0; }
    if (target == 1) { return FIB_1; }

    return calcFibonacci(target, 1, FIB_1, FIB_0);
}

private int calcFibonacci(final int target, final int previous, final int fibPrevious, final int fibPreviousMinusOne) {
    final int current = previous + 1;
    final int fibCurrent = fibPrevious + fibPreviousMinusOne;
    // If you want, print here / memoize for future calls

    if (target == current) { return fibCurrent; }

    return calcFibonacci(target, current, fibCurrent, fibPrevious);
}

1

È una sequenza di base che visualizza o ottiene un output di 1 1 2 3 5 8 è una sequenza in cui la somma del numero precedente verrà visualizzata successivamente.

Prova a guardare il link qui sotto Tutorial sequenza di Fibonacci ricorsivo Java

public static long getFibonacci(int number){
if(number<=1) return number;
else return getFibonacci(number-1) + getFibonacci(number-2);
}

Fai clic qui Guarda il tutorial sulla sequenza di Fibonacci ricorsiva Java per l'alimentazione del cucchiaio


Quello che doveva capire è come funziona il codice e perché è scritto nel modo in cui è scritto.
Adarsh,

Penso di menzionare nella mia prima frase come funziona? scrivo il codice per renderlo più semplice. a proposito, scusa.
Jaymelson Galang,

Niente di sbagliato nel tuo codice. Solo il ragazzo voleva capire come funzionava quel codice. Controlla la risposta di RanRag. Qualcosa del genere :)
Adarsh,

ahh ok, scusa sono principiante qui in StackOverflow. voglio solo aiutare ^ _ ^
Jaymelson Galang,

1

Penso che questo sia un modo semplice:

public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int number = input.nextInt();
        long a = 0;
        long b = 1;
        for(int i = 1; i<number;i++){
            long c = a +b;
            a=b;
            b=c;
            System.out.println(c);
        }
    }
}

1

La risposta RanRag (accettata) funzionerà bene ma non è una soluzione ottimizzata fino a quando non viene memorizzata come spiegato nella risposta Anil.

Per ricorsivo considerare l'approccio di seguito, le chiamate di metodo TestFibonaccisono minime

public class TestFibonacci {

    public static void main(String[] args) {

        int n = 10;

        if (n == 1) {
            System.out.println(1);

        } else if (n == 2) {
            System.out.println(1);
            System.out.println(1);
        } else {
            System.out.println(1);
            System.out.println(1);
            int currentNo = 3;
            calFibRec(n, 1, 1, currentNo);
        }

    }

    public static void calFibRec(int n, int secondLast, int last,
            int currentNo) {
        if (currentNo <= n) {

            int sum = secondLast + last;
            System.out.println(sum);
            calFibRec(n, last, sum, ++currentNo);
        }
    }

}

1
public class febo 
{
 public static void main(String...a)
 {
  int x[]=new int[15];  
   x[0]=0;
   x[1]=1;
   for(int i=2;i<x.length;i++)
   {
      x[i]=x[i-1]+x[i-2];
   }
   for(int i=0;i<x.length;i++)
   {
      System.out.println(x[i]);
   }
 }
}

1

Utilizzando una ConcurrentHashMap interna che teoricamente potrebbe consentire a questa implementazione ricorsiva di funzionare correttamente in un ambiente multithread, ho implementato una funzione fib che utilizza sia BigInteger che Recursion. Richiede circa 53ms per calcolare i primi 100 numeri di fib.

private final Map<BigInteger,BigInteger> cacheBig  
    = new ConcurrentHashMap<>();
public BigInteger fibRecursiveBigCache(BigInteger n) {
    BigInteger a = cacheBig.computeIfAbsent(n, this::fibBigCache);
    return a;
}
public BigInteger fibBigCache(BigInteger n) {
    if ( n.compareTo(BigInteger.ONE ) <= 0 ){
        return n;
    } else if (cacheBig.containsKey(n)){
        return cacheBig.get(n);
    } else {
        return      
            fibBigCache(n.subtract(BigInteger.ONE))
            .add(fibBigCache(n.subtract(TWO)));
    }
}

Il codice di test è:

@Test
public void testFibRecursiveBigIntegerCache() {
    long start = System.currentTimeMillis();
    FibonacciSeries fib = new FibonacciSeries();
    IntStream.rangeClosed(0,100).forEach(p -&R {
        BigInteger n = BigInteger.valueOf(p);
        n = fib.fibRecursiveBigCache(n);
        System.out.println(String.format("fib of %d is %d", p,n));
    });
    long end = System.currentTimeMillis();
    System.out.println("elapsed:" + 
    (end - start) + "," + 
    ((end - start)/1000));
}
e l'output del test è:
    .
    .
    .
    .
    .
    fib di 93 è 12200160415121876738
    fib di 94 è 19740274219868223167
    fib di 95 è 31940434634990099905
    fib di 96 è 51680708854858323072
    fib di 97 è 83621143489848422977
    fib di 98 è 135301852344706746049
    fib di 99 è 218922995834555169026
    fib di 100 è 354224848179261915075
    trascorso: 58,0

1

Ecco un ricorsivo febonacci a una riga:

public long fib( long n ) {
        return n <= 0 ? 0 : n == 1 ? 1 : fib( n - 1 ) + fib( n - 2 );
}

1

Prova questo

private static int fibonacci(int n){
    if(n <= 1)
        return n;
    return fibonacci(n - 1) + fibonacci(n - 2);
}

0

Solo per completare, se vuoi essere in grado di calcolare numeri più grandi, dovresti usare BigInteger.

Un esempio iterativo.

import java.math.BigInteger;
class Fibonacci{
    public static void main(String args[]){
        int n=10000;
        BigInteger[] vec = new BigInteger[n];
        vec[0]=BigInteger.ZERO;
        vec[1]=BigInteger.ONE;
        // calculating
        for(int i = 2 ; i<n ; i++){
            vec[i]=vec[i-1].add(vec[i-2]);
        }
        // printing
        for(int i = vec.length-1 ; i>=0 ; i--){
            System.out.println(vec[i]);
            System.out.println("");
        }
    }
}

0

http://en.wikipedia.org/wiki/Fibonacci_number in maggiori dettagli

public class Fibonacci {

    public static long fib(int n) {
        if (n <= 1) return n;
        else return fib(n-1) + fib(n-2);
    }

    public static void main(String[] args) {
        int N = Integer.parseInt(args[0]);
        for (int i = 1; i <= N; i++)
            System.out.println(i + ": " + fib(i));
    }

}

Renderlo semplice quanto necessario, non è necessario utilizzare while loop e altri loop


0
public class FibonacciSeries {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int N = scanner.nextInt();
        for (int i = 0; i <= N; i++) {
            int result = fibonacciSeries(i);
            System.out.println(result);
        }
        scanner.close();
    }

    private static int fibonacciSeries(int n) {
        if (n < 0) {
            return 1;
        } else if (n > 0) {
            return fibonacciSeries(n - 1) + fibonacciSeries(n - 2);
        }
        return 0;
    }
}

0

Utilizzare while:

public int fib(int index) {
    int tmp = 0, step1 = 0, step2 = 1, fibNumber = 0;
    while (tmp < index - 1) {
        fibNumber = step1 + step2;
        step1 = step2;
        step2 = fibNumber;
        tmp += 1;
    };
    return fibNumber;
}

Il vantaggio di questa soluzione è che è facile leggere il codice e comprenderlo, sperando che sia di aiuto


0

Una sequenza di Fibbonacci è quella che somma il risultato di un numero, quindi abbiamo aggiunto al risultato precedente, dovremmo partire da 1. Stavo cercando di trovare una soluzione basata sull'algoritmo, quindi ho creato il codice ricorsivo, ho notato che tengo il numero precedente e ho cambiato la posizione. Sto cercando la sequenza di Fibbonacci da 1 a 15.

public static void main(String args[]) {

    numbers(1,1,15);
}


public static int numbers(int a, int temp, int target)
{
    if(target <= a)
    {
        return a;
    }

    System.out.print(a + " ");

    a = temp + a;

    return numbers(temp,a,target);
}

-1
 public static long fib(int n) {
    long population = 0;

    if ((n == 0) || (n == 1)) // base cases
    {
        return n;
    } else // recursion step
    {

        population+=fib(n - 1) + fib(n - 2);
    }

    return population;
}

-1

Fibonacci semplice

public static void main(String[]args){

    int i = 0;
    int u = 1;

    while(i<100){
        System.out.println(i);
        i = u+i;
        System.out.println(u);
        u = u+i;
    }
  }
}

2
Benvenuti in SO. Mentre la tua risposta calcola la sequenza di Fibonacci. La tua risposta non risponde all'OP, che ha chiesto informazioni sulle funzioni ricorsive.
James K,

-2

@chro è perfetto, ma non mostra il modo corretto di farlo in modo ricorsivo. Ecco la soluzione:

class Fib {
    static int count;

    public static void main(String[] args) {
        log(fibWrong(20));  // 6765
        log("Count: " + count); // 21891
        count = 0;
        log(fibRight(20)); // 6765
        log("Count: " + count); // 19
    }

    static long fibRight(long n) {
        return calcFib(n-2, 1, 1);
    }

    static long fibWrong(long n) {
        count++;
        if (n == 0 || n == 1) {
            return n;
        } else if (n < 0) {
            log("Overflow!");
            System.exit(1);
            return n;
        } else {
            return fibWrong(n-1) + fibWrong(n-2);
        }

    }

    static long calcFib(long nth, long prev, long next) {
        count++;
        if (nth-- == 0)
            return next;
        if (prev+next < 0) {
            log("Overflow with " + (nth+1) 
                + " combinations remaining");
            System.exit(1);
        }
        return calcFib(nth, next, prev+next);
    }

    static void log(Object o) {
        System.out.println(o);
    }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.