자바 재귀 피보나치 시퀀스


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 인 경우 fibonacci (4) + fibonacci (3) 등이 호출되지만이 알고리즘이 인덱스 5의 값을 계산하는 방법을 이해하지 못하기 때문에 방법. 자세하게 설명 해주세요!


8
이것은 재귀 적이며 지수 시간으로 실행됩니다. 큰 N 값에는 비효율적입니다. 반복적 인 접근 방식을 사용하여 시퀀스에서 처음 10,000 개의 숫자를 계산할 수있었습니다. 여기에서 찾을 수 있습니다 -goo.gl/hnbF5
Adam

@AdamFisher : 10,000 개의 숫자를 계산하는 데 사용한 코드를 순서대로 공유 할 수 있습니까? 나는 실제로 그것을 알고 싶어합니다.
Shumail

4
@AdamFisher 언급하신 링크가 작동하지 않습니다.
iRuth

2
이 동영상은 10 minuts에서 재귀 함수를 이해하고 설명 할 것이다 youtube.com/watch?v=t4MSwiqfLaY
Chathura Palihakkara

2
반복하기 어려운 접근 방식도 있습니다. 코드가있는 재귀 및 반복에 대한 훌륭한 기사 -codeflex.co/java-get-fibonacci-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

코드에는 두 가지 문제가 있습니다.

  1. 결과는 정수 채우기 마이너스 비트 이후 첫 48 피보나치 수만 처리 할 수있는 int에 저장되며 결과는 잘못됩니다.
  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
"정수 채우기 빼기 비트"는 무엇을 의미합니까?
richard

1
@richard, 정수 저장 방법에 관한 것입니다. int가 2 ^ 31-1에 도달 한 후 다음 비트는 부호에 관한 것이므로 숫자는 음수가됩니다.
chro

재귀보다 훨씬 빠릅니다. 유일한 예약은 n = 1에서 작동하지 않는다는 것입니다. 추가 조건이 필요합니다
v0rin

1
"각각 2 ^ n 악화됨"은 실제로 총 함수 호출 수는 2*fibonacci(n+1)-1이므로 피보나치 수 자체와 동일한 복잡도로 증가합니다. 2 ^ n 대신 1.618 ^ n
Aemyl

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입니다. 동일한 방법론을 사용하여 다른 반복을 알아낼 수 있습니다.


이 답변이 질문을 가장 잘 설명한다고 생각합니다. 정말 간단하다
Amit

깔끔합니다. 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) (2) 내지 FIB

12

다음과 같이 기능을 단순화 할 수도 있습니다.

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

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

이것이 이것 또는 이것 또는 대답 과 다른 점은 무엇입니까?
Tunaki

6
더 짧고 읽기 쉽습니다. 어떤 알고리즘이 항상 =)
Otavio Ferreira

@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 번 호출됩니다.

자세한 내용은 dasgupta chapter 0.2의 알고리즘을 참조하십시오.


동적 프로그래밍을 사용하여 동일한 n에 대해 F (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
"여기서 for 루프가 가장 현명한 시간이라는 것을 알 수 있습니다."; "For Loop Time : 347688"; "Memoization Time : 327031"; 347688> 327031.
AjahnCharles 1

@CodeConfident 그래, 난 오늘 그 실수를 보았고 그것을 바로 잡으려고했다. 어쨌든 고마워 :).
Pritam Banerjee

7

이것은 Java에서 재귀와 피보나치 시퀀스를 완전히 설명하는 최고의 비디오입니다.

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

피보나치 재귀 솔루션의 경우 작은 피보나치 수의 출력을 저장하는 동시에 큰 수의 값을 검색하는 것이 중요합니다. 이것을 "Memoizing"이라고합니다.

여기서 사용하십시오 코드 memoizing 큰 피보나치 수를 검색하는 동안, 작은 피보나치 값. 이 코드는 효율적이며 동일한 기능을 여러 번 요청하지 않습니다.

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이고, 기타 각 항목은 이전의 두 항목의 합이다. 즉 :
0112 3 5 8 ...

5 번째 항목은 4 번째와 3 번째 항목의 합입니다.


4

Michael Goodrich 등은 [fib (n), fib (n-1)]의 배열을 반환하여 선형 시간에 피보나치를 재귀 적으로 해결하기 위해 Java의 Data Structures and Algorithms에서 정말 영리한 알고리즘을 제공합니다.

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

다음은 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);
}

위의 구현에 사용 된 Binet의 피보나치 수 공식 . 큰 입력의 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);
}

첫 번째 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;
        }

2

여기서 제공되는 대부분의 솔루션은 O (2 ^ n) 복잡성에서 실행됩니다. 재귀 트리에서 동일한 노드를 다시 계산하는 것은 비효율적이며 CPU주기를 낭비합니다.

피보나치 함수가 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 회 재귀 호출
  • 루프를 사용하여 질문을 무시합니다

(제외 : 이것들 중 어느 것도 실제로 효율적이지 않습니다; Binet의 공식 을 사용 하여 n 번째 항 을 직접 계산하십시오 )

꼬리 재귀 섬유

다음은 이전 답변과 이전 답변을 모두 전달하여 이중 재귀 호출을 피하는 재귀 적 접근 방식입니다.

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 Recursive Fibonacci sequence Tutorial 아래 링크를보십시오.

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

여기를 클릭하십시오. 숟가락 공급을위한 Java 재귀 피보나치 시퀀스 자습서


그가 이해해야 할 것은 코드의 작동 방식과 코드 작성 방식에 대한 이유입니다.
Adarsh ​​2016 년

나는 첫 문장에서 그것이 어떻게 작동하는지 언급한다고 생각합니까? 더 간단하게 코드를 작성합니다. 죄송합니다.
Jaymelson Galang

코드에 문제가 없습니다. 그 사람 만이 그 코드의 작동 방식을 이해하고 싶었습니다. RanRag의 답변을 확인하십시오. 그런 종류의 것 :)
Adarsh

아아 좋아, 미안 나는 여기에 초보자입니다. 단지 도와주고 싶어요 ^ _ ^
Jaymelson Galang

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 (허용) 답변은 잘 작동하지만 Anil 답변에 설명 된대로 암기하지 않는 한 최적화 된 솔루션이 아닙니다.

재귀 고려 아래 접근 방식의 경우 메소드 호출 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을 사용하여 BigInteger와 Recursion을 모두 사용하는 fib 함수를 구현했습니다. 처음 100 개의 fib 수를 계산하는 데 약 53ms가 걸립니다.

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));
}
테스트 결과는 다음과 같습니다.
    .
    .
    .
    .
    .
    93의 fib는 12200160415121876738입니다.
    94의 fib는 19740274219868223167입니다.
    fib 95는 31940434634990099905입니다.
    96의 fib는 51680708854858323072입니다.
    97의 fib는 83621143489848422977입니다.
    98의 fib는 135301852344706746049입니다.
    99의 fib는 218922995834555169026입니다.
    100의 fib는 354224848179261915075입니다.
    경과 : 58,0

1

다음은 한 줄의 페 보나 치 재귀입니다.

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

1

이 시도

private static int fibonacci(int n){
    if(n <= 1)
        return n;
    return fibonacci(n - 1) + fibonacci(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/Fibonacci_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));
    }

}

while 루프 및 기타 루프를 사용할 필요없이 간단하게 작성하십시오.


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에 오신 것을 환영합니다. 답변이 피보나치 수열을 계산하는 동안. 귀하의 답변에 재귀 함수에 대해 문의 한 OP에 대한 답변이 없습니다.
James K

-2

@chro는 자리에 있지만 재귀 적으로 올바른 방법을 보여주지 않습니다. 해결책은 다음과 같습니다.

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);
    }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.