web-dev-qa-db-ja.com

再帰フィボナッチ

理由を理解するのに苦労しています

#include <iostream>

using namespace std;

int fib(int x) {
    if (x == 1) {
        return 1;
    } else {
        return fib(x-1)+fib(x-2);
    }
}

int main() {
    cout << fib(5) << endl;
}

セグメンテーション違反が発生します。 xが1になったら、最終的には戻りませんか?

35
blcArmadillo

_x==2_の場合、fib(1)およびfib(0)を呼び出します。

_return fib(2-1)+fib(2-2);
_

fib(0)が評価されるとどうなるか考えてください...

150
Georg Fritzsche

その理由は、フィボナッチ数列がtwo既知のエンティティ、0および1で始まるためです。コードは、そのうちの1つ(1つ)のみをチェックします。

コードを

int fib(int x) {
    if (x == 0)
        return 0;

    if (x == 1)
        return 1;

    return fib(x-1)+fib(x-2);
}

0と1の両方を含めるには。

40
LiraNuna

なぜ反復アルゴリズムを使用しないのですか?

int fib(int n)
{
    int a = 1, b = 1;
    for (int i = 3; i <= n; i++) {
        int c = a + b;
        a = b;
        b = c;
    }           
    return b;
}
11
Dzmitry Huba

定義により、フィボナッチ数列の最初の2つの数値は1と1、または0と1です。したがって、処理する必要があります。

#include <iostream>
using namespace std;

int Fibonacci(int);

int main(void) {
    int number;

    cout << "Please enter a positive integer: ";
    cin >> number;
    if (number < 0)
        cout << "That is not a positive integer.\n";
    else
        cout << number << " Fibonacci is: " << Fibonacci(number) << endl;
}

int Fibonacci(int x) 
{
    if (x < 2){
     return x;
    }     
    return (Fibonacci (x - 1) + Fibonacci (x - 2));
}
7
Vanji

私はこの解決策は短く、素敵に見えると思います:

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

編集:jweyrichが述べたように、真の再帰関数は次のようになります:

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

(fib(0)= 0であるため、上記の再帰式に基づいているため、fib(0)は1になります)

再帰アルゴリズムを理解するために、あなたは自分の論文に描くべきであり、最も重要なことは「普通に考えてください」です。

3
hqt

これは再帰に関するフィボナッチ問題の私の解決策です。

#include <iostream>
using namespace std;

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

int main() {
    cout << fibonacci(8);
    return 0;
}
3
Pedro Eugénio
int fib(int n) {
    if (n == 1 || n == 2) {
        return 1;
    } else {
        return fib(n - 1) + fib(n - 2);
    }
}

フィボナッチ数列では、最初の2つの数値は常に1に続き、値が1または2になるたびに1を返す必要があります

2
noelyahan
int fib(int x) 
{
    if (x < 2)
      return x;
    else 
      return (fib(x - 1) + fib(x - 2));
}
1
zod
int fib(int x) 
{
    if (x == 0)
      return 0;
    else if (x == 1 || x == 2) 
      return 1;
    else 
      return (fib(x - 1) + fib(x - 2));
}
1
user2331083
if(n==1 || n==0){
    return n;
}else{     
    return fib(n-1) + fib(n-2);
}

ただし、関数は受信した数値の約8.5回呼び出されるため、フィボナッチ数を取得するために再帰を使用するのは悪い習慣です。例えば。フィボナッチ数30を取得するには(1346269)-関数は7049122回呼び出されます!

1
Jokerius

再帰を使用するフィボナッチの最良の解決策だと思います。

#include<bits/stdc++.h>
typedef unsigned long long ull;
typedef long long ll;
ull FIBO[100005];
using namespace std;
ull fibo(ull n)
{
    if(n==1||n==0)
        return n;
    if(FIBO[n]!=0)
        return FIBO[n];
    FIBO[n] = (fibo(n-1)+fibo(n-2));
    return FIBO[n];
}
int main()
{
    for(long long  i =34;i<=60;i++)
        cout<<fibo(i)<<" " ;
    return 0;
}
0

私の解決策は次のとおりです。

#include <iostream>


    int fib(int number);

    void call_fib(void);

    int main()
    {
    call_fib();
    return 0;
    }

    void call_fib(void)
    {
      int input;
      std::cout<<"enter a number\t";
      std::cin>> input;
      if (input <0)
      {
        input=0;
        std::cout<<"that is not a valid input\n"   ;
        call_fib();
     }
     else 
     {
         std::cout<<"the "<<input <<"th fibonacci number is "<<fib(input);
     }

    }





    int fib(int x)
    {
     if (x==0){return 0;}
     else if (x==2 || x==1)
    {
         return 1;   
    }

    else if (x>0)
   {
        return fib(x-1)+fib(x-2);
    }
    else 
     return -1;
    }

fib(0)= 0を返し、負の場合はエラーを返します

0
Cadence Weddle

すべてのソリューションは非効率的だと思います。結果を得るには、多くの再帰呼び出しが必要です。

unsigned fib(unsigned n) {
    if(n == 0) return 0;
    if(n == 1) return 1;
    return fib(n-1) + fib(n-2);
}

このコードは、fib(5)の結果、fin(10)の177、fib(30)の2.7kkを取得するために14の呼び出しを必要とします。

this アプローチを使用するか、再帰を使用する場合はこれを試してください:

unsigned fib(unsigned n, unsigned prev1 = 0, unsigned prev2 = 1, int depth = 2)     
{
    if(n == 0) return 0;
    if(n == 1) return 1;
    if(depth < n) return fib(n, prev2, prev1+prev2, depth+1);
    return prev1+prev2;
}

この関数では、nのフィボナッチ数を計算するためにn回の再帰呼び出しが必要です。他のすべてのパラメーターにはデフォルト値があるため、fib(10)を呼び出すことで引き続き使用できます。