为什么我的递归斐波那契实现是用 C++ 段错误编写的?

问题描述 投票:0回答:12

我很难理解为什么

#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,它最终不应该返回吗?

c++ recursion fibonacci
12个回答
151
投票

x==2
致电
fib(1)
fib(0)
时:

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

考虑评估

fib(0)
时会发生什么...


40
投票

原因是因为斐波那契数列以两个已知实体 0 和 1 开始。您的代码仅检查其中之一(是一个)。

将代码更改为

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

    if (x == 1)
        return 1;

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

同时包含 0 和 1。


10
投票

为什么不使用迭代算法?

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

7
投票

根据定义,斐波那契数列中的前两个数字是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));
}

3
投票

我认为这个解决方案很短并且看起来不错:

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)

要理解递归算法,你应该画到你的论文上,最重要的是:“经常思考”。


2
投票
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
投票

这是我用递归解决斐波那契问题的方法。

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

0
投票
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));
}

0
投票
int fib(int x) 
{
    if (x < 2)
      return x;
    else 
      return (fib(x - 1) + fib(x - 2));
}

0
投票
if(n==1 || n==0){
    return n;
}else{     
    return fib(n-1) + fib(n-2);
}

但是,使用递归来获取斐波那契数是不好的做法,因为函数被调用的次数大约是接收到的数的 8.5 次。 例如。获得斐波那契数 30 (1346269) - 函数被调用 7049122 次!


-1
投票

我的解决方案是:

#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,如果为负则返回错误


-1
投票

我认为所有这些解决方案都是低效的。他们需要大量的递归调用才能得到结果。

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

此代码需要 14 次调用才能获取 fib(5) 的结果,fin(10) 需要 177 次调用,fib(30) 需要 2.7kk 次调用。

你应该更好地使用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) 使用它,因为所有其他参数都有默认值。

© www.soinside.com 2019 - 2024. All rights reserved.