35

I'm having a hard time understanding why

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

results in a segmentation fault. Once x gets down to 1 shouldn't it eventually return?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Ian Burris
  • 6,325
  • 21
  • 59
  • 80

13 Answers13

151

When x==2 you call fib(1) and fib(0):

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

Consider what will happen when fib(0) is evaluated...

Georg Fritzsche
  • 97,545
  • 26
  • 194
  • 236
  • 74
    +1 for not giving the answer directly but indicating where the problem is. Much better for someone who is learning. – Xetius Oct 05 '09 at 08:41
  • 4
    +1, I use the same technique with my oldest kid (9) and it stimulates his ability to solve problems. – Toon Krijthe Oct 05 '09 at 11:52
40

The reason is because Fibonacci sequence starts with two known entities, 0 and 1. Your code only checks for one of them (being one).

Change your code to

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

    if (x == 1)
        return 1;

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

To include both 0 and 1.

LiraNuna
  • 64,916
  • 15
  • 117
  • 140
11

Why not use iterative algorithm?

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;
}
Spoike
  • 119,724
  • 44
  • 140
  • 158
Dzmitry Huba
  • 4,493
  • 20
  • 19
  • 3
    That’s the best approach. But he asked for a recursive solution. – Gumbo Oct 05 '09 at 08:15
  • @Gumbo, the 'best' approach would be meta-programming, no doubt. – LiraNuna Oct 05 '09 at 08:16
  • I never said it is, I know what meta-programming is, and it involves no runtime calculations *at all*. – LiraNuna Oct 05 '09 at 08:31
  • I don't want to confuse the author, since he is clearly focusing on recursion. If you want to know more, visit http://en.wikipedia.org/wiki/Template_metaprogramming – LiraNuna Oct 05 '09 at 08:38
  • 13
    A metaprogramming approach would basically boil down to a recursive solution...the calculation would simply be transfered from runtime to compile-time. Claiming that this would be a better approach is non-sense because we don't know the OP requirements: if he just needs to run the program once, having a huge compile time and a short runtime is not better than having a short compile time and a long runtime. Similarly, if he needs to take as input the 'n' parameter, metaprogramming is not usable (except if you explicitely put an upper bound to this number). Moreover, compilers have a limited... – Luc Touraille Oct 05 '09 at 09:51
  • 6
    ...recursion depth, so this can be an issue. To sum up, metaprogramming is a really powerful tool, but should be wisely used, only when it truly fits the problem. – Luc Touraille Oct 05 '09 at 09:54
  • For the OP's benefit it has to be said: In 99% of real life situations, iterative run-time solution is the only option. Iterative solution is *much* faster than wrong recursive template based solution. And *much* slower vs a proper recursive template based solution. https://wandbox.org/permlink/43Gb20ACqmvQHdhT –  Nov 19 '18 at 11:22
7

By definition, the first two numbers in the Fibonacci sequence are 1 and 1, or 0 and 1. Therefore, you should handle it.

#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));
}
Vanji
  • 1,696
  • 14
  • 23
3

I think this solution is short and seem looks nice:

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

Edit : as jweyrich mentioned, true recursive function should be:

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

(because fib(0) = 0. but base on above recursive formula, fib(0) will be 1)

To understand recursion algorithm, you should draw to your paper, and the most important thing is : "Think normal as often".

hqt
  • 29,632
  • 51
  • 171
  • 250
  • 1
    `fib(0)` wrongly results in 1. This would solve: `return x < 2 ? x : fibonnaci(x-1) + fibonnaci(x-2);`. Here an extra condition exclusively for `fib(2)` would just slow down the function. – jweyrich Oct 28 '13 at 17:53
  • often fibonnaci function n just runs up to about 50 with recursive call. I don't think additional condition will slow down the `recursive call` – hqt Oct 28 '13 at 18:04
  • 1
    My point was that your `fib` function returns the wrong result for `fib(0)`. Please, ignore the rest :-) – jweyrich Oct 28 '13 at 18:13
3

This is my solution to fibonacci problem with recursion.

#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;
}
2
int fib(int n) {
    if (n == 1 || n == 2) {
        return 1;
    } else {
        return fib(n - 1) + fib(n - 2);
    }
}

in fibonacci sequence first 2 numbers always sequels to 1 then every time the value became 1 or 2 it must return 1

noelyahan
  • 4,195
  • 1
  • 32
  • 27
1
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
int fib(int x) 
{
    if (x < 2)
      return x;
    else 
      return (fib(x - 1) + fib(x - 2));
}
zod
  • 21
  • 2
1
if(n==1 || n==0){
    return n;
}else{     
    return fib(n-1) + fib(n-2);
}

However, using recursion to get fibonacci number is bad practice, because function is called about 8.5 times than received number. E.g. to get fibonacci number of 30 (1346269) - function is called 7049122 times!

Jokerius
  • 1,310
  • 1
  • 14
  • 22
0

My solution is:

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

it returns fib(0)=0 and error if negitive

0

I think it's the best solution of fibonacci using recursion.

#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

I think that all that solutions are inefficient. They require a lot of recursive calls to get the result.

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

This code requires 14 calls to get result for fib(5), 177 for fin(10) and 2.7kk for fib(30).

You should better use this approach or if you want to use recursion try 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;
}

This function requires n recursive calls to calculate Fibonacci number for n. You can still use it by calling fib(10) because all other parameters have default values.