Рекурсивна послідовність Java в Фібоначчи


156

Поясніть, будь ласка, цей простий код:

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

Мені плутають останній рядок, особливо тому, що якщо, наприклад, n = 5, тоді буде викликано поле (4) + поле (3) тощо, але я не розумію, як цей алгоритм розраховує значення за індексом 5 за цим метод. Поясніть, будь ласка, дуже детально!


8
Зауважте, що це рекурсивно і працює в експоненціальному часі. Це неефективно для великих значень N. Використовуючи ітеративний підхід, я зміг обчислити перші 10 000 чисел у послідовності. Їх можна знайти тут - goo.gl/hnbF5
Адам

@AdamFisher: Чи можете ви поділитися кодом, який ви використовували для обчислення 10000 чисел послідовно? Я насправді цікаво знати це.
Shumail

4
@AdamFisher Посилання, про яке ви згадували, мертве.
iRuth

2
Це відео пояснить розуміння рекурсивної функції через 10 хвилин youtube.com/watch?v=t4MSwiqfLaY
Chathura Palihakkara

2
Існує також ітеративний підхід, який може бути для вас менш складним. Чудова стаття про рекурсивний та ітеративний з кодом тут - codeflex.co/java-get-fibach-number-by-index
user5495300

Відповіді:


165

У послідовності вирівнювань кожен елемент - це сума попередніх двох. Отже, ви написали рекурсивний алгоритм.

Так,

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

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

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

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

Тепер ви вже знаєте fibonacci(1)==1 and fibonacci(0) == 0. Отже, згодом ви можете обчислити інші значення.

Тепер,

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

І з послідовності фільтрів 0,1,1,2,3,5,8,13,21....ми можемо бачити, що 5th elementпослідовність фіналів повертається 5.

Дивіться тут навчальний посібник з рекурсії .


він буде працювати, але не оптимізований до тих пір, поки не буде оптимізовано. Будь ласка, подивіться на мою відповідь. Повідомте мене у разі пропозицій / коментарів
M Sach

52

З кодом є 2 проблеми:

  1. Результат зберігається в int, який може обробляти лише перші 48 номерів поля, після цього цілочисельне заповнення мінус біт і результат неправильний.
  2. Але ви ніколи не можете запустити поле (50).
    Код
    fibonacci(n - 1) + fibonacci(n - 2)
    дуже неправильний.
    Проблема полягає в тому, що вона називає не в 50 разів, а набагато більше.
    Спочатку він називає поле (49) + фігура (48),
    наступний (48) + фільтр (47) і рівень (47) + фігура (46)
    Кожен раз, коли він стає гіршим (n), тому складність експоненціальна. введіть тут опис зображення

Підхід до нерекурсивного коду:

 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
Хоча деякі інші відповіді пояснюють рекурсію чіткіше, це, мабуть, найбільш відповідна відповідь на більш глибокому рівні.
Hal50000

1
Що означає "ціле заповнення мінус біт"?
Річард

1
@richard, мова йде про те, як зберігається ціле число. Після того, як int досяг 2 ^ 31-1, наступний біт є знаком, тому число стає негативним.
chro

Набагато швидше, ніж рекурсивний. Єдине застереження полягає в тому, що він не працюватиме при n = 1. Необхідна додаткова умова
v0rin

1
"Кожен раз, коли він ставав на 2 ^ n гірше", фактично кількість загальних викликів функцій є 2*fibonacci(n+1)-1, тому вона зростає з тією ж складністю, що і самі цифри поля, що становить 1,618 ^ n замість 2 ^ n
Еміль

37

У псевдокоді, де n = 5, відбувається наступне:

поле (4) + фібоначі (3)

Це розпадається на:

(поле (3) + фібоначі (2)) + (поле (2) + фібоначі (1))

Це розпадається на:

((((2) + фібонач (1)) + ((поле (1) + фібонач (0))) + (((поле (1) + фібонач (0)) + 1))

Це розпадається на:

((((((1) + фібонахи (0)) + 1) + ((1 + 0)) + ((1 + 0) + 1))

Це розпадається на:

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

Це призводить до: 5

Враховуючи послідовність фібоначків 1 1 2 3 5 8 ... , 5-й елемент - 5. Ви можете використовувати ту саму методологію, щоб визначити інші ітерації.


Я думаю, що ця відповідь найкращим чином пояснює питання. Дійсно просте
Аміт

Це акуратно. Пояснює як значення на n-му члені, так і ряд, з якого випливає.
Кома

12

Рекурсію іноді важко зрозуміти. Просто оцініть це на аркуші паперу на невелику кількість:

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 насправді оцінює це, але результат буде таким же.


на другому рядку звідки беруться в кінці 1 і 0?
pocockn

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

Отже, у вас є fib (4), тому n-1 і n-2 буде fib (3) + fib (2), тоді ви знову зробите n-1 і n-2, ви отримаєте -> fib (2) + fib (1 ), звідки ви отримали + fib (1) + fib (0)? Додано в кінці
pocockn

@pocockn fib (2) + fib (1) є з fib (3), fib (1) + fib (0) є з fib (2)
tim

12

Ви також можете спростити свою функцію так:

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

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

Чим це відрізняється, ніж ця чи ця чи ця відповідь?
Тунакі

6
Це просто коротше і легше читати, які алгоритми завжди повинні бути =)
Отавіо Феррейра

@OtavioFerreira Єдина відповідь, яка вдалося вирішити мою проблему, хороша робота
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)

Важливим моментом є те, що цей алгоритм є експоненціальним, оскільки він не зберігає результат попередніх обчислених чисел. наприклад, F (n-3) називається 3 рази.

Більш детально див. Алгоритм, описаний у розділі 0.2


Існує методологія програмування, за допомогою якої ми можемо уникати обчислення F (n) для того ж n знову і знову, використовуючи Динамічне програмування
Amit_Hora

8

Більшість відповідей хороші та пояснюють, як працює рекурсія у фіг.

Ось аналіз трьох методів, що включає також рекурсію:

  1. Для циклу
  2. Рекурсія
  3. Пам'ятка

Ось мій код для тестування всіх трьох:

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

}

Ось результати:

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

Отже, ми можемо бачити, що запам’ятовування - це найкращий час та уважно відповідає циклу.

Але рекурсія триває найдовше і, можливо, вам цього слід уникати в реальному житті. Також якщо ви використовуєте рекурсію, переконайтеся, що ви оптимізували рішення.


1
"Тут ми можемо побачити, що цикл - це найкращий час"; "Час циклу: 347688"; «Час пам’яті: 327031»; 347688> 327031.
AjahnCharles

@CodeConfident Так, я щойно побачив цю помилку і збирався її виправити. Спасибі все одно :).
Pritam Banerjee

7

Це найкраще відео, яке я знайшов, що повністю пояснює рекурсію та послідовність Фібоначчі на Яві.

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

Це його код для послідовності, і його пояснення краще, ніж я міг коли-небудь намагатися ввести його.

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

Для рекурсивного рішення, важливо зберегти вихід менших цифр, одночасно отримуючи значення більшої кількості. Це називається «Пам'ять».

Ось код, який використовує запам'ятовування менших значень поля , отримуючи при цьому більший номер поля . Цей код ефективний і не робить кілька запитів однієї функції.

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

в Фібоначчі послідовності, перші два елементи є 0 і 1, кожен другий елемент є сумою двох попередніх пунктів. тобто:
0 1 1 2 3 5 8 ...

тому 5-й пункт - це сума 4-го та 3-го предметів.


4

Майкл Гудріч та ін надають дійсно розумний алгоритм в структурах даних та алгоритмах на Java для вирішення рекурсивної напруги у лінійному часі шляхом повернення масиву [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;
    }
}

Це дає fib (n) = fibGood (n) [0].


4

Ось рішення (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);
}

Формула чисел Фібоначчі Біне, що використовується для здійснення вище. Для великих входів longможна замінити на BigDecimal.


3

Послідовність Фібоначчі - це та, яка підсумовує результат числа при додаванні до попереднього результату, починаючи з 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);
}

Перший, якщо statment перевіряє базовий випадок, де цикл може вирватися. Інакше, якщо твердження нижче, що робить те саме, але воно може бути переписане так ...

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

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

Тепер, коли встановлено базовий випадок, ми повинні зрозуміти стек викликів. Ваш перший виклик до "Fliw" буде останнім, хто вирішить на стеку (послідовності викликів), оскільки вони вирішуються у зворотному порядку, з якого вони були викликані. Останній названий метод вирішується спочатку, потім останній, який слід викликати перед цим і так далі ...

Отже, усі дзвінки здійснюються спочатку, перш ніж все "підраховано" з цими результатами. При введенні 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;
        }

2

Більшість запропонованих тут рішень виконують складність O (2 ^ n). Перерахунок однакових вузлів у рекурсивному дереві неефективний і витрачає цикли процесора.

Ми можемо використовувати мемуалізацію, щоб змусити функцію напруженості виконувати в 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];
}

Якщо ми будемо слідувати маршруту програмування динамічного знизу вгору, то нижче код досить простий для обчислення рівня:

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

Чому ця відповідь різна

Будь-яка інша відповідь:

  • Друкує замість повернень
  • Здійснює 2 рекурсивні дзвінки за ітерацію
  • Ігнорує питання за допомогою циклів

(вбік: жодне з них насправді не є ефективним; використовуйте формулу Біне для прямого обчислення n- го терміна)

Хвост рекурсивний Fib

Ось рекурсивний підхід, який дозволяє уникнути подвійного рекурсивного дзвінка шляхом передачі як попередньої відповіді, так і тієї, що передує.

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, це послідовність того, що сума попереднього числа поточне число буде відображатися наступним.

Спробуйте переглядати посилання нижче Посібник з послідовності рекурсивної фібоначки Java

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

Натисніть тут Переглянути навчальний посібник з послідовності фібоначчі Java для годування ложкою


Що йому потрібно було зрозуміти - це як працює код і чому він пишеться так, як він написаний.
Adarsh

Я думаю, я згадую в своєму першому реченні, як це працює? Я пишу код, щоб зробити його більш простим. btw, вибачте.
Джеймельсон Галанг

Нічого поганого у вашому коді. Тільки хлопець хотів зрозуміти, як працює цей код. Перевірте відповідь RanRag. Щось такого роду :)
Adarsh

ах, добре, вибачте, я початківець тут, в stackoverflow. просто хочу допомогти ^ _ ^
Джеймельсон Галанг

1

Я думаю, що це простий спосіб:

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 (прийнято) буде добре працювати, але це не оптимізоване рішення до тих пір, і поки воно не запам'ятовується, як пояснено у відповіді Аніла.

Для рекурсивного розгляду нижче підходу, виклики методів TestFibonacciмінімальні

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

Використовуючи внутрішній ConcurrentHashMap, який теоретично може дозволити цій рекурсивній реалізації належним чином працювати в багатопотоковому середовищі, я реалізував функцію fib, яка використовує як BigInteger, так і рекурсію. Для обчислення перших 100 фібрових чисел потрібно близько 53 мс.

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
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));
}
і вихід з тесту:
    .
    .
    .
    .
    .
    fib 93 є 12200160415121876738
    fib 94 - 19740274219868223167
    fib 95 - 31940434634990099905
    fib 96 є 51680708854858323072
    fib 97 - 83621143489848422977
    fib 98 - 135301852344706746049
    фіб 99 є 218922995834555169026
    фіб 100 є 354224848179261915075
    минуло: 58,0

1

Ось один рядок фебоначчі рекурсивний:

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


0

Просто для доповнення, якщо ви хочете мати можливість обчислити великі числа, вам слід скористатися BigInteger.

Ітеративний приклад.

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/Fibach_number більш детально

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

}

Зробіть так просто, як потрібно, не потрібно використовувати цикл та інші петлі


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

Використання 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;
}

Перевага цього рішення полягає в тому, що легко прочитати код і зрозуміти його, сподіваючись, що це допоможе


0

Послідовність Фібоначчі - це така, яка підсумовує результат числа, тоді ми додали до попереднього результату, ми повинні почати з 1. Я намагався знайти рішення на основі алгоритму, тому я будував рекурсивний код, помітив, що я зберігаю попередній номер, і я змінив позицію. Я шукаю послідовність Фібоначчі від 1 до 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

Прості Фібоначчі

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. Поки ваша відповідь обчислює послідовність Фібоначчі. Ваша відповідь не відповідає ОП, який запитав про рекурсивні функції.
Джеймс К

-2

@chro увімкнено, але s / він не показує правильний спосіб зробити це рекурсивно. Ось рішення:

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);
    }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.