I'm in the basic of the basic of learning c++, and ran into an example of recursion that I don't understand. The equation is for Fibonacci numbers, and is shown below:
int fibo(int f)
{
if (f < 3)
{
return 1;
}
else
{
return fibo(f - 2) + fibo(f - 1);
}
}
How does the "else" statement work? I know that it adds the two previous numbers to get the current fibbonacci number, but how does it know, without any prior information, where to start? If I want the 7th fibonacci number, how does it know what the 6th and 5th numbers are?
In this given equation, It will go deeper in the root. When you have given Value 7 initially, it will go to function itself to get value of 7-2 = 5 and 7-1=6, still its has not value of 5 and 6. so further it will decrease value of 5 to 3 and 4 and 6 to 5 and 4.
at the end when f is less then 3 it will return value 1. something like that after getting root values it will sum up those values to get total answer.
A recursive function will call itself as many times as it needs to compute the final value. For example, if you call fibo(3), it will call itself with fibo(2) and fibo(1).
You can understand it better if you write down a tree representing all the function calls (the numbers in brackets are the return values):
fibo(3) [1+1]
|
.--------------.
| |
fibo(2) [1] fibo(1) [1]
For fibo(7), you will have multple calls like so:
fibo(7) [fibo(6) + fibo(5)]
|
.-----------------------------------------------.
| |
fibo(6) [fibo(5) + fibo(4)] fibo(5) [fibo(4) + fibo(3)]
| |
.---------------------------------. ...
| |
fibo(5) [fibo(4) + fibo(3)] fibo(4) [fibo(3) + fibo(2)]
| |
... ...
Each recursive call will execute the same code, but with a different value of f. And each recursive call will have to call their own "editions" of the sub-cases (smaller values). This happens until everyone reaches the base case (f < 3).
I didn't draw the entire tree. But I guess you can see this grows very quick. There's a lot of repetition (fibo(7) calls fibo(6) and fibo(5), then fibo(6) calls fibo(5) again). This is why we usually don't implement Fibonacci recursively, except for studying recursion.
Related
I am learning recursion in my current class and the idea is a little tricky for me. From my understanding, when we build a function it will run as many times until our "base case" is satisfied. What I am wondering is how this looks and is returned on the stack. For an example I wrote the following function for a simple program to count how many times a digit shows up in an integer.
What does this look and work in a stack frame view? I don't completely understand how the returning works. I appreciate the help!
int count_digits(int n, int digit) {
// Base case: When n is a single digit.
if (n / 10 == 0) {
// Check if n is the same as the digit.
// When recursion hits the base case it will end the recursion.
if (n == digit) {
return 1;
} else {
return 0;
}
} else {
if (n % 10 == digit) {
return (1 + count_digits(n / 10, digit));
} else {
return (count_digits(n / 10, digit));
}
}
}
What does this look and work in a stack frame view? I don't completely understand how the returning works. I appreciate the help!
Let's try to build the solution bottom-up.
If you called the function - int count_digits(int n, int digit) as count_digits(4, 4) what would happen ?
This is the base case of your solution so it is very easy to see what is the return value. Your function would return 1.
Now, let's add one more digit and call the function like- count_digits(42, 4). What would happen ?
Your function will check the last digit which is 2 and compare with 4 since they are not equal so it will call the function count_digits(4, 4) and whatever is the returned value, will be returned as the result of count_digits(42, 4).
Now, let's add one more digit and call the function like - count_digits(424, 4). What would happen ?
Your function will check the last digit which is 4 and compare with 4 since they are equal so it will call the function count_digits(42, 4) and whatever is the returned value, will be returned by adding 1 to it. Since, number of 4s in 424 is 1 + number of 4s in 42. The result of count_digits(42,4) will be calculated exactly like it was done previously.
The recursive function builds up the solution in a top-down manner. If there are n digits initially, then your answer is (0 or 1 depending on the last digit) + answer with n-1 digits. And this process repeats recursively. So, your recursive code, reduces the problems by one digit at a time and it depends on the result of the immediate sub-problem.
You can use the C++ tutor at pythontutor.com website for step by step visualization of the stack frame. http://pythontutor.com/cpp.html#mode=edit
You can also try with smaller inputs and add some debug output to help you track and see how recursion works.
Check this stackoverflow answer for understanding what a stack frame is - Explain the concept of a stack frame in a nutshell
Check this stackoverflow answer for understanding recursion -
Understanding recursion
If you would like more help, please let me know in comments.
I have this code in VBA (looping through the array a() of type double):
bm = 0 'tot
b = 0 'prev
For i = 24 To 0 Step -1
BP = b 'prevprev = prev
b = bm 'prev = tot
bm = T * b - BP + a(i) 'tot = a(i) + T * prev - prevprev
Next
p = Exp(-xa * xa) * (bm - BP) / 4 '* (tot - prevprev)/4
I'm putting this in F#. Clearly I could use an array and mutable variables to recreate the VBA. And maybe this is an example of the right time to use mutable that I've seen hinted at. But why not try to do it the most idiomatic way?
I could write a little recursive function to replicate the loop. But it kind of feels like littering to hang out a little sub-loop that has no meaning on its own as a standalone, named function.
I want to do it with List functions. I have a couple ideas, but I'm not there yet. Anyone get this in a snap??
The two vague ideas I have are: 1. I could make two more lists by chopping off one (and two) elements and adding zero-value element(s). And combine those lists. 2. I'm wondering if a list function like map can take trailing terms in the list as arguments. 3. As a general question, I wonder if this might be a case where an experienced person would say that this problem screams for mutable values (and if so does that dampen my enthusiasm for getting on the functional boat).
To give more intuition for the code: The full function that this is excerpted from is a numerical approximation for the cumulative normal distribution. I haven't looked up the math behind this one. "xa" is the absolute value of the main function argument "x" which is the number of standard deviations from zero. Without working through the proof, I don't think there's much more to say than: it's just a formula. (Oh and maybe I should change the variable names--xa and bm etc are pretty wretched. I did put suggestions as comments.)
It's just standard recursion. You make your exit condition and your recur condition.
let rec calc i prevPrev prev total =
if i = 0 then // exit condition; do your final calc
exp(-xa * xa) * (total - prevPrev) / 4.
else // recur condition, call again
let newPrevPrev = prev
let newPrev = total
let newTotal = (T * newPrev - newPrevPrev + a i)
calc (i-1) newPrevPrev newPrev newTotal
calc 24 initPrevPrev initPrev initTotal
or shorter...
let rec calc i prevPrev prev total =
if i = 0 then
exp(-xa * xa) * (total - prevPrev) / 4.
else
calc (i-1) prev total (T * total - prev + a i)
Here's my try at pulling the loop out as a recursive function. I'm not thrilled about the housekeeping to have this stand alone, but I think the syntax is neat. Aside from an error in the last line, that is, where the asterisk in (c * a.Tail.Head) gets the red squiggly for float list not matching type float (but I thought .Head necessarily returned float not list):
let rec RecurseIt (a: float list) c =
match a with
| []-> 0.0
| head::[]-> a.Head
| head::tail::[]-> a.Head + (c * a.Tail) + (RecurseIt a.Tail c)
| head::tail-> a.Head + (c * a.Tail.Head) - a.Tail.Tail.Head + (RecurseIt a.Tail c)
Now I'll try list functions. It seems like I'm going to have to iterate by element rather than finding a one-fell-swoop slick approach.
Also I note in this recursive function that all my recursive calls are in tail position I think--except for the last one which will come one line earlier. I wonder if this creates a stack overflow risk (ie, prevents the compiler from treating the recursion as a loop (if that's the right description), or if I'm still safe because the algo will run as a loop plus just one level of recursion).
EDIT:
Here's how I tried to return a list instead of the sum of the list (so that I could use the 3rd to last element and also sum the elements), but I'm way off with this syntax and still hacking away at it:
let rec RecurseIt (a: float list) c =
match a with
| []-> []
| head::[]-> [a.Head]
| head::tail::[]-> [a.Head + (c * a.Tail)] :: (RecurseIt a.Tail c)
| head::tail-> [a.Head + (c * a.Tail.Head) - a.Tail.Tail.Head] :: (RecurseIt a.Tail c)
Here's my try at a list function. I think the problem felt more complicated than it was due to confusing myself. I just had some nonsense with List.iteri here. Hopefully this is closer to making sense. I hoped some List. function would be neat. Didn't manage. For loop not so idiomatic I think. :
for i in 0 .. a.Length - 1 do
b::
a.Item(i) +
if i > 0 then
T * b.Item(i-1) -
if i > 1 then
b.Item(i-2)
else
0
else
0
Hello I have a homework question I am stuck in..any hint or tips would be appreciated. the questions is:
Write a single recursive function in C++ that takes as argument a positive integer n then print n, n-1, n-2,...3,2,1,2,3,...n. How many recursive call does your algorithm makes? What is the worst case running time of your algorithm?
I am stuck in the first part. writing a recursive function that prints n, n-1, n-2,...3,2,1,2,3,...n
so far I have:
print(int n)
{
if (n==0)
return;
cout<<n<<" ";
print(n-1);
return;
}
but this only prints from n to 1
I am lost about how I would print from 2 to n using just one parameter and recursively single function.
I tried this: which gives the correct output but has a loop and has two parameters:
p and z has the same value.
void print(int p,int z)
{
if (p==0)
{
for(int x=2;x<=z; x++)
cout<<x<<" ";
return;
}
else
cout<<p<<" ";
print(p-1,z);
return;
}
any hint or tips is much appreciated thank you.
so it is working now, but I am having trouble understanding how (question in comment):
void print(int n)
{
if (n==1){
cout<<n;
return;
}
else
cout<< n;
print(n-1); // how does it get passed this? to the line below?
cout<<n; // print(n-1) takes it back to the top?
return;
}
The output you want is mirrored, so you can have this series of steps:
print num
recursive step on num-1
print num again
That's the recursive case. Now you need an appropriate base case upon which to stop the recursion, which shouldn't be difficult.
Given the pseudocode:
recursive_print(n):
if n == 1:
print 1
return
print n
recursive_print(n-1)
print n
(If you prefer, just look at your solution instead).
Let's trace it. A dot will mark where we're up to in terms of printing.
. recursive_print(3) // Haven't printed anything
3 . recursive_print(2) 3 // Print the 3
3 2 . recursive_print(1) 2 3 //Print 2
3 2 1 . 2 3 // Print 1
3 2 1 2 . 3 // Print 2
3 2 1 2 3 . // Print 3
Each unrolling of the function gives us 2 numbers on opposite sides and we build down to the "1", then go back and print the rest of the numbers.
The "unrolling" is shown in this picture:
If you strip away the functions and leave yourself with a sequence of commands, you'll get:
print 3
print 2
print 1
print 2
print 3
where each indentation signifies a different function.
Simple solution for this:
Def fxn(n):
if n <= n:
if n > 0:
print(n)
fxn(n - 1)
print(n)
Def main():
Number = 6
fxn(Number)
Main()
If you struggle understanding how this works:
Basically, each time you call a function in a recursive problem, it isn't a loop. It's as if you were on the woods leaving a trail behind. Each time you call a function inside a function, it does its thing, then it goes right back to were you called it.
In other words, whenever you call a recursive function, once the newer attempt is done, it will go right back to were it used to be.
In loops, once each step is done, it is done, but in recursive functions you can do a lot with a lot less.
Printing before the recurse call in my code is the descension step, and once its descension finished, it will progresively unfold step by step, printing the ascension value and going back to the former recurse.
It seems way harder than it is, but it is really easy once you grasp it.
The answer is simpler than you think.
A recursive call is no different from a regular call. The only difference is that the function called is also the caller, so you need to make sure you don't call it forever (you already did that). Let's think about a regular call. If you have the following code snippet:
statement1
f();
statement2
The statement1 is executed, then f is called and does it's thing and then, after f finishes, statement2 is executed.
Now, let's think about your problem. I can see that your hard work on this question from the second program you've written, but forget about it, the first one is very close to the answer.
Let's think about what your function does. It prints all numbers from n to 0 and then from 0 to n. At the first step, you want to print n, then all the numbers from n-1 to 0 and from 0 to n-1, and print another n. See where it's going?
So, you have to do something like this:
print(n)
call f(n-1)
print(n)
I hope my explanation is clear enough.
This is more of hack -- using the std::stream rather than recursion...
void rec(int n) {
if (n==1) { cout << 1; return; }
cout << n;
rec(n-1);
cout << n;
}
int main() {
rec(3);
}
prints
32123
I am having doubt on recursion, if I write the code like shown below
inorder(p){
if(p!=NULL){
inorder(p->link); //step 1
cout<<p->info<<" "; //step 2
inorder(p->link); //step 3
}
}
Here, my doubt is that when step 1 is executed the control goes back to the function and then again the step 1 executes and again the control will go back to the function up to p is NULL, if this is the process then how control will come to step 2 which is "cout" and to step 3 ...
I am unable to cycle the code in my brain...
Before the "control goes back to the same function" in step 1, CPU makes an important step: it marks the place in code of inorder where it needs to restart execution once "the second level" of inorder returns (that's the spot right after step 1). There, the "second level" marks the return position again before going to the "third level", the "fourth level", and so on. Eventually, the N-th level gets a NULL, so it returns right away. Then the N-1-th level gets to print the info, and proceed to call inorder for the second time. Now the return location is different - it's right after step 3. Once N-th level finishes, N-1-st level finishes as well, going back to N-2-nd level, then to N-3-rd, and so on, until the very first level exits.
Here is an example tree:
A
/ \
B C
/ \
D E
The process of inorder traversal goes like this:
inorder(A) -- step 1, level 1
inorder(B) -- step 1, level 2
inorder(NULL) -- returns
cout << B -- step 2, level 2
inorder(NULL) -- returns
return -- level 2 returns
cout << A -- step 2, level 1
inorder(C) -- step 3, level 2
inorder(D) -- step 1, level 3
inorder(NULL) -- returns
cout << D -- step 2, level 3
inorder(NULL) -- returns
return -- level 3 returns
cout << C -- step 2, level 2
inorder(E) -- step 1, level 3
inorder(NULL) -- returns
cout << E -- step 2, level 3
inorder(NULL) -- returns
return -- level 3 returns
return -- level 2 returns
return -- level 1 returns
you should learn about call stack if you want to understand how the recursion works. Here is the link.
Hope this will help...
Suppose p points to A, p->link (that is, A.link) is called q and points to B, and q->link (which is to say B.link) is NULL, call it r.
p q r
----->A----->B----->0
Now we call inorder(p).
p is not NULL, so inorder(p) calls inorder(q) (step 1)
q is not NULL, so inorder(q) calls inorder(r) (step 1)
r is NULL, so inorder(r) skips the block and returns control to inorder(q)
inorder(q) prints B.info (step 2)
inorder(q) calls inorder(r) (step 3) which again returns control to inorder(q), which returns control to inorder(p)
inorder(p) prints A.info (step 2)
inorder(p) calls inorder(q) (step 3), which runs through 2-5 again (printing B.info again), then inorder(p) returns control to whatever called it.
The first time I bumped into recursion was with a factorial function.
Factorial is a basic function in maths, given a number N, it returns a number equal to the product of all positive integers less than N.
Consider this simple code in C++ which nicely demonstrates recursion.
int fact(int x)
{
if(x==1)
return 1;
x = x*fact(x-1);
return x;
}
This inputs an integer, and then calls itself after decrementing the integer until the integer is 1, and returns x. Note that the line 'return x;' is not called until the line before it finishes.
When the first call to inorder(p->link) is made, consider it as a checkpoint. It will keep calling to a point it reaches NULL. Then line 2 is executed and the same is followed for the second call to inorder(p->link). So this forms a tree
inorder(p->link) -> coutinfo -> inorder(p->link)
/ ^ / ^
V / V /
inorder()->cout->inorder() inorder()->cout->inorder()
. ^ / \ . ^ / \
. | . . . | . .
. | . |
inorder(p->link) //(p->link is NULL) inorder(p->link) //(p->link is NULL)
I assume that your code is correct. You are trying to print out a linked list in the below fashion:
inorder(p){
if(p!=NULL)
{
inorder(p->link); //step 1 to navigate to next link
cout<<p->info<<" "; //step 2 as main operation
inorder(p->link); //step 3 to navigate to next link
}
}
Translate into English
inorder(p)
{
if p points to a linked list
{
print the list p points to;
print content of p;
print the list p points to again;
}
if p points to a null linked list
{
do nothing;
}
}
Then a linked list of 1 -> 2 -> 3 will output ((3) 2 (3)) 1 ((3) 2 (3))
As you can see, the control will only pass to step 2 once step 1 encounters a null linked list. After the info is printed out, it is then passed to step 3.
Therefore,
When linked list at node "3",
step 1 encounters null and return;
step 2 prints out 3;
step 3 encounters null and return;
When linked list at node "2"
step 1 performs whatever it does at node "3"; // print 3
step 2 prints out 2;
step 3 performs whatever it does at node "3"; // print 3
when linked list at node "1"
step 1 performs whatever it does at node "2"; // print 3 2 3
step 2 prints out 1;
step 3 performs whatever it does at node "2"; // print 3 2 3
Consider a game, were you have 5 messages left at different places in your house. Each message leads you to the next. To win the game, you must find all 5 messages and return them to the game host. However, you cannot pick up the messages as you find them... you must remember their location and pick them up in the opposite order you found them.
You would walk to the first item, make a note of where it is and follow the clue; keeping a mental note to where you need to return later to pick up the clue. You would do the same with the next 4 clues.
When you find the last clue, so no more exist, you would then start to work backwards, returning to where you found each clue, retrieving them.
Finding the first clue is like your first call to "inorder()". Following the clue to the second clue is like your call to "inorder(p->link)". Picking up the clue after all clues have been found is like when you return to "step2" in your code.
Each time the function inorder is called, data (referred to as an activation frame or frame) is put on data structure referred to as a call stack. Each frame keeps track of data local to the function, such as parameters passed into the function, a pointer to the activation frame of the function caller and, importantly, the address of the next line of code to be executed in the calling function. So as you recursively call inorder, you are recursively adding frames to this stack and each frame contains an address to the next line of code that should be executed when the corresponding function is finished and control is returned to the function caller.
In other words, when you call inorder from line referred to as step 1 and the passed in parameter p is NULL, when the function exits, the calling function will start execution at the line referred to as step 2.
See the wikipedia page http://en.wikipedia.org/wiki/Call_stack for more info.
Understanding the concepts related to call stacks will help in understanding what is going on with recursion.
while practicing recursive functions, I have written this code for fibonacci series and (factorial) the program does not run and shows the error "Control reaches end of non-void function" i suspect this is about the last iteration reaching zero and not knowing what to do into minus integers. I have tried return 0, return 1, but no good. any suggestions?
#include <cstdlib>
#include <iomanip>
#include <iostream>
#include <ctime>
using namespace std;
int fib(int n) {
int x;
if(n<=1) {
cout << "zero reached \n";
x= 1;
} else {
x= fib(n-1)+fib(n-2);
return x;
}
}
int factorial(int n){
int x;
if (n==0){
x=1;
}
else {
x=(n*factorial(n-1));
return x;
}
}
Change
else if (n==1)
x=1;
to
else if (n==1)
return 1;
Then fib() should work for all non-negative numbers. If you want to simplify it and have it work for all numbers, go with something like:
int fib(int n) {
if(n<=1) {
cout << "zero reached \n";
return 1;
} else {
return fib(n-1)+fib(n-2);
}
}
"Control reaches end of non-void function"
This is a compile-time warning (which can be treated as an error with appropriate compiler flags). It means that you have declared your function as non-void (in this case, int) and yet there is a path through your function for which there is no return (in this case if (n == 1)).
One of the reasons that some programmers prefer to have exactly one return statement per function, at the very last line of the function...
return x;
}
...is that it is easy to see that their functions return appropriately. This can also be achieved by keeping functions very short.
You should also check your logic in your factorial() implementation, you have infinite recursion therein.
Presumably the factorial function should be returning n * factorial(n-1) for n > 0.
x=(factorial(n)*factorial(n-1)) should read x = n * factorial(n-1)
In your second base case (n == 1), you never return x; or 'return 1;'
The else section of your factorial() function starts:
x=(factorial(n)*factorial(n-1));
This leads to infinite recursion. It should be:
x=(n*factorial(n-1));
Sometimes, your compiler is not able to deduce that your function actually has no missing return. In such cases, several solutions exist:
Assume
if (foo == 0) {
return bar;
} else {
return frob;
}
Restructure your code
if (foo == 0) {
return bar;
}
return frob;
This works good if you can interpret the if-statement as a kind of firewall or precondition.
abort()
(see David RodrÃguez's comment.)
if (foo == 0) {
return bar;
} else {
return frob;
}
abort(); return -1; // unreachable
Return something else accordingly. The comment tells fellow programmers and yourself why this is there.
throw
#include <stdexcept>
if (foo == 0) {
return bar;
} else {
return frob;
}
throw std::runtime_error ("impossible");
Not a counter measure: Single Function Exit Point
Do not fall back to one-return-per-function a.k.a. single-function-exit-point as a workaround. This is obsolete in C++ because you almost never know where the function will exit:
void foo(int&);
int bar () {
int ret = -1;
foo (ret);
return ret;
}
Looks nice and looks like SFEP, but reverse engineering the 3rd party proprietary libfoo reveals:
void foo (int &) {
if (rand()%2) throw ":P";
}
Also, this can imply an unnecessary performance loss:
Frob bar ()
{
Frob ret;
if (...) ret = ...;
...
if (...) ret = ...;
else if (...) ret = ...;
return ret;
}
because:
class Frob { char c[1024]; }; // copy lots of data upon copy
And, every mutable variable increases the cyclomatic complexity of your code. It means more code and more state to test and verify, in turn means that you suck off more state from the maintainers brain, in turn means less maintainer's brain quality.
Last, not least: Some classes have no default construction and you would have to write really bogus code, if possible at all:
File mogrify() {
File f ("/dev/random"); // need bogus init
...
}
Do not do this.
There is nothing wrong with if-else statements. The C++ code applying them looks similar to other languages. In order to emphasize expressiveness of C++, one could write for factorial (as example):
int factorial(int n){return (n > 1) ? n * factorial(n - 1) : 1;}
This illustration, using "truly" C/C++ conditional operator ?:, and other suggestions above lack the production strength. It would be needed to take measures against overfilling the placeholder (int or unsigned int) for the result and with recursive solutions overfilling the calling stack. Clearly, that the maximum n for factorial can be computed in advance and serve for protection against "bad inputs". However, this could be done on other indirection levels controlling n coming to the function factorial. The version above returns 1 for any negative n. Using unsigned int would prevent dealing processing negative inputs. However, it would not prevent possible conversion situation created by a user. Thus, measures against negative inputs might be desirable too.
While the author is asking what is technically wrong with the recursive function computing the Fibonacci numbers, I would like to notice that the recursive function outlined above will solve the task in time exponentially growing with n. I do not want to discourage creating perfect C++ from it. However, it is known that the task can be computed faster. This is less important for small n. You would need to refresh the matrix multiplication knowledge in order to understand the explanation. Consider, evaluation of powers of the matrix:
power n = 1 | 1 1 |
| 1 0 | = M^1
power n = 2 | 1 1 | | 1 1 | | 2 1 |
| 1 0 | * | 1 0 | = | 1 1 | = M^2
power n = 3 | 2 1 | | 1 1 | | 3 2 |
| 1 1 | * | 1 0 | = | 2 1 | = M^3
power n = 4 | 3 2 | | 1 1 | | 5 3 |
| 2 1 | * | 1 0 | = | 3 2 | = M^4
Do you see that the matrix elements of the result resemble the Fibonacci numbers? Continue
power n = 5 | 5 3 | | 1 1 | | 8 5 |
| 3 2 | * | 1 0 | = | 5 3 | = M^5
Your guess is right (this is proved by mathematical induction, try or just use)
power n | 1 1 |^n | F(n + 1) F(n) |
| 1 0 | = M^n * | F(n) F(n - 1) |
When multiply the matrices, apply at least the so-called "exponentiation by squaring". Just to remind:
if n is odd (n % 2 != 0), then M * (M^2)^((n - 1) / 2)
M^n =
if n is even (n % 2 == 0), then (M^2)^(n/2)
Without this, your implementation will get the time properties of an iterative procedure (which is still better than exponential growth). Add your lovely C++ and it will give a decent result. However, since there is no a limit of perfectness, this also can be improved. Particularly, there is a so-called "fast doubling" for the Fibonacci numbers. This would have the same asymptotic properties but with a better time coefficient for the dependence on time. When one say O(N) or O(N^2) the actual constant coefficients will determine further differences. One O(N) can be still better than another O(n).