Java özyinelemeli Fibonacci dizisi


156

Lütfen bu basit kodu açıklayın:

public int fibonacci(int n)  {
    if(n == 0)
        return 0;
    else if(n == 1)
      return 1;
   else
      return fibonacci(n - 1) + fibonacci(n - 2);
}

Özellikle n = 5 ise, o zaman fibonacci (4) + fibonacci (3) çağrılırdı çünkü son satır ile karıştırıyorum ama bu algoritma bu indeks 5 değerini nasıl hesapladığını anlamıyorum yöntem. Lütfen çok ayrıntılı olarak açıklayın!


8
Bunun özyinelemeli olduğunu ve üstel zamanda çalıştığını unutmayın. N'nin büyük değerleri için verimsizdir. Yinelemeli bir yaklaşım kullanarak dizideki ilk 10.000 sayıyı hesaplayabildim. Burada bulunabilirler - goo.gl/hnbF5
Adam

@AdamFisher: 10.000 rakamı hesaplamak için kullandığınız kodu sırayla paylaşabilir misiniz? Aslında bunu merak ediyorum.
Shumail

4
@AdamFisher Belirttiğiniz bağlantı öldü.
iRuth

2
Bu video 10 dakika içinde özyinelemeli işlevi anlamak için açıklayacaktır youtube.com/watch?v=t4MSwiqfLaY
Chathura Palihakkara

2
Ayrıca, sizin için daha az zor olabilecek yinelemeli bir yaklaşım da vardır. Buradaki kodla Yinelemeli ve Yinelemeli hakkında harika bir makale - codeflex.co/java-get-fibonacci-number-by-index
user5495300

Yanıtlar:


165

Fibonacci dizisinde, her madde bir önceki ikisinin toplamıdır. Böylece, özyinelemeli bir algoritma yazdınız.

Yani,

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

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

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

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

Şimdi zaten biliyorsun fibonacci(1)==1 and fibonacci(0) == 0. Böylece, daha sonra diğer değerleri hesaplayabilirsiniz.

Şimdi,

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

Ve Fibonacci dizisinden 0,1,1,2,3,5,8,13,21....biz görebilirsiniz 5th elementFibonacci dizisi döndürür 5.

Özyineleme Eğitimi için buraya bakın .


çalışır, ancak optimize edilmedene kadar optimize edilmez. Lütfen benim cevabımıza bir göz atın. Öneri / yorum durumunda bana bildirin
M Sach

52

Kodunuzla ilgili 2 sorun var:

  1. Sonuç sadece ilk 48 fibonacci sayısını işleyebilen int içinde saklanır, bundan sonra tamsayı doldurma eksi biti ve sonuç yanlıştır.
  2. Fakat asla fibonacci kullanamazsınız (50).
    Kod
    fibonacci(n - 1) + fibonacci(n - 2)
    çok yanlış.
    Sorun şu ki, fibonacci'yi 50 kez değil, çok daha fazla çağırıyor.
    İlk önce fibonacci (49) + fibonacci (48),
    sonraki fibonacci (48) + fibonacci (47) ve fibonacci (47) + fibonacci (46)
    her seferinde fibonacci (n) daha kötü hale gelir, bu nedenle karmaşıklık üsteldir. resim açıklamasını buraya girin

Özyinelemesiz koda yaklaşım:

 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
Diğer cevapların bazıları özyinelemeyi daha açık bir şekilde açıklasa da, bu muhtemelen daha derin bir düzeyde en uygun cevaptır.
Hal50000

1
"Tamsayı dolum eksi bit" ne anlama gelir?
richard

1
@richard, tamsayının nasıl saklandığıyla ilgilidir. İnt 2 ^ 31-1'e ulaştıktan sonra bir sonraki bit işaret ile ilgilidir, bu nedenle sayı negatif olur.
chro

Özyinelemeden çok daha hızlı. Tek rezervasyon, n = 1 için çalışmaz olmasıdır. Ek koşul gereklidir
v0rin

1
"Her seferinde 2 ^ n daha da kötüleşti" aslında toplam fonksiyon çağrılarının sayısı 2*fibonacci(n+1)-1, yani fibonacci sayıları ile aynı karmaşıklıkla büyür, bu da 2 ^ n yerine 1.618 ^ n'dir
Aemyl

37

Sahte kodda, n = 5 olduğunda, aşağıdakiler gerçekleşir:

fibonacci (4) + fibonacacci (3)

Bu şu şekilde ayrılır:

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

Bu şu şekilde ayrılır:

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

Bu şu şekilde ayrılır:

((((fibonacci (1) + fibonacacci (0)) + 1) + ((1 + 0)) + ((1 + 0) + 1))

Bu şu şekilde ayrılır:

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

Bunun sonucu: 5

Fibonacacci dizisi 1 1 2 3 5 8 ... olduğu için, 5. element 5'tir. Diğer iterasyonları anlamak için aynı metodolojiyi kullanabilirsiniz.


Bence bu cevap soruları en iyi şekilde açıklıyor. Gerçekten basit
Amit

Bu temiz. Hem n. Terimdeki değeri hem de izlediği seriyi açıklar.
Noktalı virgül

12

Özyinelemeyi bazen kavramak zor olabilir. Sadece küçük bir sayı için bir kağıt üzerinde değerlendirin:

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

Java'nın bunu nasıl değerlendirdiğinden emin değilim, ama sonuç aynı olacak.


ikinci satırda sondaki 1 ve 0 nereden geliyor?
pocockn

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

Yani fib (4) var, bu yüzden n-1 ve n-2 fib (3) + fib (2) olur, sonra n-1 ve n-2'yi tekrar alırsınız -> fib (2) + fib (1 ) nereden + fib (1) + fib (0) aldınız? Sonuna Eklendi
Pocockn

@ pocockn fib (2) + fib (1) fib (3), fib (1) + fib (0) fib (2) 'den
tim

12

Ayrıca, aşağıdaki gibi işlevinizi basitleştirebilirsiniz:

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

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

Nasıl bundan daha farklıdır bu ya bu ya bu cevap?
Tunaki

6
Hangi algoritmaların her zaman olması gerektiği daha kısa ve daha kolay, =)
Otavio Ferreira

@OtavioFerreira sorunumu çözmeyi başaran tek cevap, iyi iş
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)

Dikkat edilmesi gereken önemli nokta, bu algoritmanın daha önce hesaplanan sayıların sonucunu saklamadığı için üstel olmasıdır. örneğin F (n-3) 3 kez çağrılır.

Daha fazla ayrıntı için dasgupta bölüm 0.2'ye göre algoritmaya bakın


Dinamik Programlama'yı kullanarak aynı n için tekrar tekrar F (n) hesaplamaktan kaçınabileceğimiz bir programlama metodolojisi vardır
Amit_Hora

8

Cevapların çoğu iyidir ve fibonacci'deki özyinelemenin nasıl çalıştığını açıklar.

İşte özyineleme de içeren üç teknik üzerinde bir analiz:

  1. Döngü için
  2. özyineleme
  3. memoization

İşte üçünü de test etmek için kodum:

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

}

Sonuçlar burada:

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

Bu yüzden hatırlamanın en akıllıca zaman olduğunu görebiliriz ve döngü eşleşmeleri için .

Ancak özyineleme en uzun sürer ve gerçek hayatta kaçınmanız gerekebilir. Ayrıca özyineleme kullanıyorsanız çözümü optimize ettiğinizden emin olun.


1
"Burada döngü için en iyi zaman bilge görebilirsiniz"; "Döngü Süresi için: 347688"; "Memoizasyon Zamanı: 327031"; 347688> 327031.
AjahnCharles

@CodeConfident Evet, bu hatayı bugün gördüm ve düzeltmek üzereydim. Yine de teşekkürler :).
Pritam Banerjee

7

Bu, Java'daki özyineleme ve Fibonacci dizisini tam olarak açıklayan bulduğum en iyi video.

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

Bu onun dizisi için kodudur ve açıklaması bunu yazmaya çalışırken yapabileceğimden daha iyidir.

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

Fibonacci özyinelemeli çözüm için, daha büyük sayının değerini alırken, daha küçük fibonacci sayılarının çıktısını kaydetmek önemlidir. Buna "Memoizing" denir.

İşte daha büyük fibonacci sayısını alırken, daha küçük fibonacci değerlerini hatırlamak kullanan bir kod . Bu kod etkilidir ve aynı işlev için birden fazla istekte bulunmaz.

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

içerisinde Fibonacci sekansı, ilk iki ürün 0 ve 1, birbirini takip et önceki iki öğe toplamıdır. yani:
0 1 1 2 3 5 8 ...

yani 5. madde 4. ve 3. maddelerin toplamıdır.


4

Michael Goodrich ve arkadaşları, bir dizi [fib (n), fib (n-1)] döndürerek fibonacci'yi lineer zamanda yinelemeli olarak çözmek için Java'daki Veri Yapıları ve Algoritmalarda gerçekten akıllı bir algoritma sağlar.

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

Bu fib (n) = fibGood (n) [0] verir.


4

İşte O (1) çözümü:

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

Binet'in yukarıdaki uygulama için kullanılan Fibonacci sayı formülü . Büyük girişler longile değiştirilebilir BigDecimal.


3

Bir Fibbonacci dizisi, 1 ile başlayan önceki sonuca eklendiğinde bir sayının sonucunu toplayan dizidir.

      so.. 1 + 1 = 2
           2 + 3 = 5
           3 + 5 = 8
           5 + 8 = 13
           8 + 13 = 21

Fibbonacci'nin ne olduğunu anladıktan sonra, kodu parçalamaya başlayabiliriz.

public int fibonacci(int n)  {
    if(n == 0)
        return 0;
    else if(n == 1)
      return 1;
   else
      return fibonacci(n - 1) + fibonacci(n - 2);
}

İlk if ifadesi, döngünün dağılabileceği bir temel durumu kontrol eder. Aşağıdaki ifadenin aynısını yapıyorsa, ancak bu şekilde yeniden yazılabilirse ...

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

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

Şimdi bir temel durum oluşturulduktan sonra çağrı yığınını anlamalıyız. "Fibonacci" ye ilk çağrınız, çağrıldıkları ters sırayla çözüldükleri için yığında (çağrıların sırası) çözülecek son çağrı olacaktır. Denilen son yöntem önce çözülür, sonra ondan önce çağrılacak son yöntem vb.

Böylece, tüm aramalar bu sonuçlarla bir şey "hesaplanmadan" önce yapılır. 8'lik bir girdi ile 21'lik bir çıktı bekliyoruz (yukarıdaki tabloya bakın).

fibonacci (n - 1) baz kasasına ulaşana kadar çağrılmaya devam eder, daha sonra fibonacci (n - 2) baz kasasına ulaşana kadar çağrılır. Yığın sonucu ters sırada toplamaya başladığında, sonuç şöyle olur ...

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).

Yığındaki ilk çağrıya doğru toplam geri dönene kadar köpürmeye devam eder (geriye doğru çözümlenir) ve cevabınızı bu şekilde alırsınız.

Bunu söyledikten sonra, bu algoritma çok verimsizdir çünkü kodun ayrıldığı her dal için aynı sonucu hesaplar. Çok daha iyi bir yaklaşım, Memoization (önbellekleme) veya özyineleme (derin çağrı yığını) gerekmeyen "aşağıdan yukarıya" bir yaklaşımdır.

Bunun gibi ...

        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

Burada sunulan çözümlerin çoğu O (2 ^ n) karmaşıklığında çalışır. Özyinelemeli ağaçta özdeş düğümleri yeniden hesaplamak verimsizdir ve CPU döngülerini harcar.

Fibonacci fonksiyonunun O (n) zamanında çalışmasını sağlamak için notu kullanabiliriz

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

Aşağıdan Yukarı Dinamik Programlama yolunu izlersek, aşağıdaki kod fibonacci'yi hesaplamak için yeterince basittir:

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

Bu cevap neden farklı?

Diğer cevaplar:

  • İade yerine yazdırır
  • Yineleme başına 2 özyinelemeli çağrı yapar
  • Döngüler kullanarak soruyu yok sayar

(kenara: bunlardan hiçbirinin etkilidir; kullanımı Binet formülü ile doğrudan N hesaplamak için th dönem)

Kuyruk Özyinelemeli Fib

İşte hem önceki yanıtı hem de ondan önceki cevabı geçerek çift yinelemeli bir çağrıyı önleyen özyinelemeli bir yaklaşım.

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

1 1 2 3 5 8'i görüntüleyen veya çıkaran temel bir dizidir, geçerli sayının önceki sayının toplamının bir sonraki görüntüleneceği bir dizidir.

Aşağıdaki bağlantıyı izlemeye çalışın Java Özyinelemeli Fibonacci dizisi Eğitimi

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

Tıklayın İzle Java Recursive Fibonacci dizisi Eğitimi kaşık maması için


Anlaması gereken, kodun nasıl çalıştığı ve neden yazıldığıdır.
Adarsh

Sanırım ilk cümlemde nasıl çalıştığını söyledim? daha basit hale getirmek için kod yazmak. btw, özür dilerim.
Jaymelson Galang

Kodunuzda yanlış bir şey yok. Bu kodun nasıl çalıştığını sadece adam anlamak istedi. Cevabı RanRag tarafından kontrol edin. Bu tür bir şey :)
Adarsh

ahh tamam, üzgünüm burada stackoverflow acemiyim. ^ _ ^
Jaymelson Galang

1

Bunun basit bir yol olduğunu düşünüyorum:

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

RanRag (kabul edilen) cevabı iyi çalışır ancak Anil cevabında açıklandığı gibi ezberlenene kadar ve optimize edilmemiş bir çözümdür.

Özyinelemeli olarak aşağıdaki yaklaşımı düşünün, yöntem çağrıları TestFibonacciminimumdur

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

Teorik olarak bu özyinelemeli uygulamanın çok iş parçacıklı bir ortamda düzgün çalışmasına izin verebilecek bir dahili ConcurrentHashMap kullanarak, hem BigInteger hem de Özyineleme kullanan bir fib işlevi uyguladım. İlk 100 fib sayısını hesaplamak yaklaşık 53ms sürer.

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

Test kodu:

@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));
}
ve testten çıktı:
    .
    .
    .
    .
    .
    93'ün fiberi 12200160415121876738'dir
    94 fiberi 19740274219868223167'dir
    95'in fiberi 31940434634990099905
    96'nın fiberi 51680708854858323072'dir
    97'nin fiberi 83621143489848422977'dir
    98'in fiberi 135301852344706746049
    99 fiberi 218922995834555169026
    100'ün fiberi 354224848179261915075
    Geçen: 58,0

1

İşte tek satırlık febonacci özyinelemeli:

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

1

Bunu dene

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

0

Sadece tamamlamak için, daha büyük sayıları hesaplamak istiyorsanız, BigInteger'i kullanmalısınız.

Yinelemeli bir örnek.

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 daha ayrıntılı olarak

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

}

Döngü ve diğer döngüleri kullanmaya gerek kalmadan gerektiği kadar basit olun


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

Kullanım 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;
}

Bu çözümün avantajı, kodu okumanın ve anlamanın kolay olması,


0

Bir Fibbonacci dizisi, bir sayının sonucunu toplayan bir sayıdır, o zaman önceki sonuca ekledik, 1'den başlamalıyız. Algoritmaya dayalı bir çözüm bulmaya çalışıyordum, bu yüzden özyinelemeli kodu oluşturdum, önceki sayı ve ben pozisyon değiştirdim. 1'den 15'e kadar Fibbonacci dizisini arıyorum.

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

Basit Fibonacci

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
SO hoş geldiniz. Cevabınız Fibonacci dizisini hesaplarken. Cevabınız, özyinelemeli işlevler hakkında soru soran OP'ye cevap vermiyor.
James K

-2

@chro açık, ancak bunu yinelemeli olarak yapmanın doğru yolunu göstermiyor. İşte çözüm:

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);
    }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.