Ok, I initially wrote a simple code to return the Fibonacci number from the series based on the user input..
n=5 will produce 3..
static int fibonacci(in
Recursively is a very inefficient way to calculate the Fibonacci number.After the number 43 it will take more then 30 sec till you'll have the answer. I tried to find out how much time will take to calculate the number 52 and it took about 47 minutes. So the time grows very fast.
The recursive code:
private int calculateRecursivelyInt(int fnum)
{
if (fnum == 0)
return 0;
if (fnum == 1)
return 1;
return calculateRecursivelyInt(fnum - 1) + calculateRecursivelyInt(fnum - 2);
}
Loops are much more efficient
//This method will be able to calculate till the F46 because int can't hold a
// bigger number. You can calculate till 92 with a type long and till 93 with
// unsigned long in C#.
private int calculateLoopInt(int num)
{
int fnum = 0;
int val1 = 0;
int val2 = 1;
for (int i = 0; i < num; i++)
{
if (num == 1)
fnum = 1;
else if (i > 0)
{
fnum = val1 + val2;
val1 = val2;
val2 = fnum;
}
}
return fnum;
}
The right way to do it is use accumlator.
the code should look something like this (i didn't check it, it's only the idea)
static int fibonacci(int n, int accumlator) {
if (n == 1)
return 0;
else if (n == 2)
return 1;
else
accumlator = (fibonacci(n - 1, accumlator) + fibonacci(n - 2, accumlator));
return accumlator;
}
Your modification to your fibonacci
program does indeed work to calculate sums. However, the way you have used recursion is inefficient. One way to deal with this is with a "dynamic programming" approach, where calculated values are cached so that they can be re-used by the second recursive call. However, the n-th Fibonacci number can be forward calculated from the base. A recursive implementation of this would be:
public static int fib_r (int a, int b, int n) {
if (n == 1) return a;
if (n == 2) return b;
return fib_r(b, a+b, n-1);
}
public static int fib (int n) {
return fib_r(0, 1, (n > 0) ? n : 1);
}
The corresponding code for the sum would be:
public static int sumfib_r (int a, int b, int n) {
if (n == 1) return a;
if (n == 2) return b;
return sumfib_r(b, a+b+1, n-1);
}
public static int sumfib (int n) {
return sumfib_r(0, 1, (n > 0) ? n : 1);
}
Tail recursion will often be changed by the compiler/interpreter into a simple loop as part of tail call removal.
You asked:
I still couldn't figure out how the summation of the series works if I add 1. Can someone please explain??
This question is really about understanding the algorithm, which I would suppose is topical on SO. But, math is required to describe why the algorithm works. So, this is really a math question. There is a well known theorem regarding the sum of Fibonacci numbers. If F[i]
is the i-th Fibonacci number, and S[n]
is the sum of the first n
Fibonacci numbers, then the theorem above states:
S[n] = F[n+2] - 1
So, if we consider that by definition of S[n+2]
,
S[n+2] = S[n+1] + F[n+2]
Then, substituting S[n] + 1
for F[n+2]
:
S[n+2] = S[n+1] + S[n] + 1
Which you should recognize is your "add 1 modified" fibonacci
function.
Below is a proof by induction that your program computes the sum that I provided in my original answer. Let F
represent your fibonacci
function, and let S
represent your "add 1 modified" fibonacci
function.
F[1] = 0
F[2] = 1
F[i] = F[i-1] + F[i-2] for i > 1
S[1] = 0
S[2] = 1
S[i] = S[i-1] + S[i-2] + 1 for i > 1
Then, you want a proof that for k > 0
:
k
.---
S[k] = > F[i]
`---
i = 1
Note that the above summation is true if and only if:
S[1] = F[1]
S[k] = F[k] + S[k-1] for k > 1
The proof is fairly straight forward. The base cases are trivially true.
S[1] = F[1] = 0
S[2] = F[2] + F[1] = 1
S[3] = S[2] + S[1] + 1 = F[3] + F[2] + F[1] = 2
The induction step is: Given that for some k > 2
, S[j+1] = F[j+1] + S[j]
for 0 < j < k+1
, prove that the equality holds true if j = k+1
, that is: S[k+2] = F[k+2] + S[k+1]
.
S[k+2] = S[k+1] + S[k] + 1
=> S[k+2] = (F[k+1] + S[k]) + (F[k] + S[k-1]) + 1
=> S[k+2] = (F[k+1] + F[k]) + (S[k] + S[k-1] + 1)
=> S[k+2] = F[k+2] + S[k+1]
This completes the proof.
another approach to print Fibonacci series using recursive function.
#include <iostream>
// 0 1 1 2 3 5 8 13...
//
void fibb (int idx, int curr = 0, int next = 0)
{
std::cout << curr << ", ";
if(!idx) return;
if(curr == 0) {
curr = 1;
fibb(--idx, curr, next);
return;
}
next += curr;
fibb(--idx, next, curr);
}
int main()
{
fibb(10);
}
No it won't. The second version of the code does not compute the sum of all the values of the fibonacci function up to the given value. And the base cases are wrong, too!
If you want to calculate the sum recursively, split the problem in two parts, like this:
public static int fib(int n) {
return n < 2 ? n : fib(n-1) + fib(n-2);
}
public static int sumfib(int n) {
return n < 0 ? 0 : fib(n) + sumfib(n-1);
}
The first function calculates fibonacci, the second takes care of adding the values up to a given number.
Your code needs to test for n<1
- if you pass an argument of 0 or less, it will go on forever...
Other than that - if you call fib(5)
, here is what happens:
...
return(fib(4) + fib(3))
fib(4):
return(fib(3) + fib(2))
fib(3):
return(fib(2) + fib(1))
now fib(2) == 1 by your definition, and fib(1) == 0
so fib(3) == 1
then fib(4) == 1 + 1 = 2
and fib(5) = fib(4) + fib(3) = 2 + 1 = 3
Now if you add the '+1', the following happens:
fib(1) and fib(2) are unchanged
fib(3) = 1 + 0 + 1 = 2
fib(4) = fib(3) + fib(2) + 1 = 4
fib(5) = fib(4) + fib(3) + 1 = 4 + 2 + 1 = 7
Your original method is good, but it depends on how you consider the "order" of a Fibonacci number (what do you want the first number to be).