Recursion on C++ that returning backwards - c++

Here is the code:
#include <iostream>
using namespace std;
void countdown(int n);
int main(){
countdown(4); // call the recursive function
return 0;
}
void countdown(int n){
cout << n << endl;
if (n > 0){
countdown(n-1); // function calls itself
}
cout << n << endl; // intended part of code
}
Simple run :
4
3
2
1
0
0
1
2
3
4
Question: why does this recursive function counts back up from 0 to 4 and do not stop at 0?

Because recursion function call is stored in stack. So, when one function call returns, it is popped out of stack and then it executes the next line of the function call.
void countdown(int n){
cout << n << endl; // This line calls 4 3 2 1 0
if (n > 0){
countdown(n-1); // function calls itself
}
cout << n << endl;; //This line print 0 1 2 3 4
}
Suppose the numbers before the line of the code are the line numbers:
1 void countdown(int n){
2 cout << n << endl; // This line calls 4 3 2 1 0
3 if (n > 0){
4 countdown(n-1); // function calls itself
5 }
6 cout << n << endl;; //This line print 0 1 2 3 4
7 }
Suppose countdown is called with n = 2,
Then, Your stack will initially contain function call with n = 2.
Because of line 2, 2 gets printed.
Because of line 4, function with n = 1 gets called. So, now stack has 1|2
Now because of line 2 again, 1 gets printed.
Because of line 4, function with n = 0 gets called. So Now stack is 0|1|2
Line 2 prints 0.
Line 3 condition fails and so line 4 is not executed.
Line 6 prints 0.
Line 7 tells that function execution is over and hence it will pop out of stack. Now stack is 1|2.
Now, function with n = 1 resumes its operation from line 5.
So, line 6 makes it print 1.
line 7 tells that function execution is over and hence it will pop out of stack. Now stack is 2.
So, function with n =2 resumes its operation from line 5.
line 6 makes it print 2.
line 7 tells function execution is over and hence it will pop out of stack. And now it will return to main.

You print n twice - before calling the function recursively, and then again after it returns. If you only want to print the number counting down, just print it once:
void countdown(int n) {
cout << n << endl;
if (n > 0){
countdown(n-1);
}
// Another cout call was removed here...
}

To put it very simply, calling a function - even your own function - does not end execution of the current function. Consider the following:
void countdown() {
std::cout << countdown << "\n";
}
int main() {
countdown();
std::cout << "main\n";
}
you would not be surprised that this prints
countdown
main
Nor would you be surprised if you wrote:
int main() {
int i = 0;
if (i == 0)
countdown();
std::cout << "main\n";
}
We can also simply demonstrate that a recursive function backtracks through its call points like this:
#include <iostream>
void countdown(int n) {
std::cout << "countdown(" << n << ") entry\n";
if (n == 0)
countdown(n + 1);
std::cout << "countdown(" << n << ") exit\n";
}
int main() {
std::cout << "main entry\n";
countdown(0);
std::cout << "main exit\n";
}
live demo
outputs:
main entry
countdown(0) entry
countdown(1) entry
countdown(1) exit
countdown(0) exit
main exit

You have two output lines. Remove the last cout << n << endl. That last line is what is counting back up, after returning from the recursive call.

because of the second cout just before the end of the coutdown function

Related

Understanding the Order of Execution of Recursive Functions

template <typename T>
T sum(stack<T>& s){
if (s.empty()){
return 0;
} else {
T first = s.top();
s.pop();
T total = sum(s)+first;
s.push(first);
return total;
}
}
The code above is designed to recursively sum the elements of any given stack of type T with the only condition being that the integrity of the stack must be restored at the end of the function. Meaning, I am allowed to make changes to the stack to sum the elements as long as it is in the same state as it was before it was passed when the function terminates.
As you will observe the given code works however I do not understand the control flow or execution sequence of the recursive calls and return statements. When I see this code I understand how the elements are summed, however I do not understand how the call to "s.push(first)" adds all of the elements back on to the stack. I'm having a hard time wrapping my head around why it wouldn't solely push the last element of the stack and then return the total.
My current understanding of why this works is incomplete and likely flawed and is as follows: because each return statement returns to the most recent caller, when the recursion hits the base case and terminates, the return statements will work their way back up the recursive call stack until it gets to the original caller and therefore executing "s.push()" at each movement back up the stack.
What is causing confusion for me is the execution sequence once the stack is empty and I think it is due to a lack of understanding the way the function recurses back up the call stack. If someone could lay out the execution sequence and explain the way recursion works with operations underneath the recursive call that would me much appreciated.
Thanks!
Your overall understanding is correct. You're only missing connecting the final dots.
The key point to remember is when a function returns, it returns to wherever it was called from. Recursive functions are no different in that fundamental respect. Recursive function calls work exactly the same way.
It will help to understand if you label each recursive call. Let's call the initial invocation of the recursive function "A". When the recursive function calls itself, recursively, call that invocation of the recursive function "B". Then it calls again, and that's "C". Followed by "D", and so on.
The key point to understand is that when a function returns, it returns to wherever it was called from. So, "D" returns to "C", which returns to "B", and it returns to "A".
Now look at your recursive function. When the stack had one value left, let's call it "D", it removes the "D" value from the stack and makes the recursive call "E", which discovers that the stack is empty.
So it returns to "D", which pushes the "D" value back to the stack, which now has one value again. Then it returns to "C", which pushes the "C" value back to the stack, which now has the two original, last, values on the stack, in the same order.
In this fashion, the function calls unwind in reverse order from their original calling sequence, restoring the stack to exactly what it was, originally.
Your function looks something like this:
if (s.empty()){
return 0;
} else {
T first = s.top();
s.pop();
T total = sum(s)+first;
s.push(first);
return total;
}
To kind of see how this works, let's pretend that this is actually a macro, and expand the function into what would generally get executed:
if (s.empty()){
return 0;
} else {
T first = s.top();
s.pop();
T total = if (s.empty()){
return 0;
} else {
T first = s.top();
s.pop();
T total = sum(s)+first;
s.push(first);
return total;
}+first;
s.push(first);
return total;
}
This is of course, just an example. Since it is not a macro,this isn't what really happens. It is just to illustrate.
However, the point is that the code in your function will get executed every time you call the function similarly to the second code snippet. Thus, what ends up happening is that the innermost function pushes to the stack, and then the calling function pushes to the stack, etc.. until everything gets pushed back on to the stack. So, even though there is one call to push on the stack, it will still get executed every time the function executes.
"If someone could lay out the execution sequence ... "
It is always allowed to add (removable) cout's to the executing code. The following illustrates one approach.
Note 1: To simplify, I removed template issues. The demo uses int.
Note 2: dumpStack is not recursive.
Note 3: m_stck is data attribute of the class, so it need not be passed from sumStack to sumStack.
#include <iostream>
using std::cout, std::endl; // c++17
#include <iomanip>
using std::setw, std::setfill;
#include <string>
using std::string, std::to_string;
#include <stack>
using std::stack;
#ifndef DTB_PCKLRT_HH
#include "../../bag/src/dtb_pclkrt.hh"
using DTB::PClk_t;
#endif
class StackW_t // stack wrapper UDT (user defined type)
{
private:
int m_N; // max elements
stack<int> m_stck; // default ctor creates an empty stack
public:
StackW_t(int N = 10) // simple default size
{
m_N = N; // capture
assert(m_N > 1); // check value
for (int i=0; i<m_N; ++i)
m_stck.push(N - i); // simple fill
}
~StackW_t() = default; // dtor default deletes each element of m_stck
// recurse level-vvvv
int sumStack(int rLvl = 1)
{
if (m_stck.empty())
{
cout << "\n" << setw(2*rLvl) << " " << setw(4) << "<empty>";
return 0;
}
else
{
int first = m_stck.top(); // top element
m_stck.pop(); // remove top element
cout << "\n" << setw(2*rLvl)
<< " " << setw(4) << first; // recurse report
// use first value then recurse into smaller stack with next rLvl
int sum = first + sumStack(rLvl+1);
cout << "\n" << setw(2*rLvl) // decurse report
<< " " << setw(3) << "(" << first << ")";
m_stck.push(first); // restore element after use
return sum;
}
}
void dumpStack(string lbl, int rLvl = 1)
{
stack<int> l_stck = m_stck; // for simplicity, use copy of
cout << "\n dumpStack " << lbl << setw(2*rLvl);
while (!l_stck.empty())
{
cout << " " << " " << l_stck.top();
l_stck.pop(); // remove displayed member
}
cout << "\n";
}
}; // class StackW_t
// Functor 829
class F829_t // use compiler provided defaults for ctor and dtor
{
PClk_t pclk; // posix clock access
public:
int operator()(int argc, char* argv[]) { return exec(argc, argv); }
private:
int exec(int , char** )
{
int retVal = 0;
// create, auto fill with value 1..10
StackW_t stk;
stk.dumpStack("before"); // invoke display
cout << "\n stk.sumStack(): ";
uint64_t start_us = pclk.us();
// invoke recursive compute, start at default rLvl 1
int sum = stk.sumStack();
auto duration_us = pclk.us() - start_us;
cout << "\n sum: " << sum << endl;
stk.dumpStack("after"); // invoke display
cout << "\n F829_t::exec() duration "
<< duration_us << " us (" << __cplusplus << ")" << std::endl;
return retVal;
}
}; // class F829_t
int main(int argc, char* argv[]) { return F829_t()(argc, argv); }
Note 4: during recurse, rLvl increases, so the value shifts to the right for each line
Note 5: during decurse, rLvl is restored upon function return, thus output is also restored to alignment
Note 6: before and after of stack shows successful restore of stack
Output:
dumpStack before 1 2 3 4 5 6 7 8 9 10
stk.sumStack():
1
2
3
4
5
6
7
8
9
10
<empty>
(10)
(9)
(8)
(7)
(6)
(5)
(4)
(3)
(2)
(1)
sum: 55
dumpStack after 1 2 3 4 5 6 7 8 9 10

Why does this function print 1 2 3 4 5 in ascending order

I tried searching the answer but was not able to get any convincing answer. Can someone please explain me how does this c++ code print 1 2 3 4 5?
I understood up until the point when n=1. when n=1, fun(n-1) = fun(1-1) = fun(0) is not executed as n>0 is not satisfied, hence now cout << n << endl will be executed and n is still equal to 1 but then after printing 1 it should stop ? How does it go to the previous calls? How does it print 2 3 4 5?
Also when cout << n << endl is above fun(n-1) it makes sense as it prints 5 4 3 2 1.
#include <iostream>
using namespace std;
void fun(int n)
{
if (n > 0) {
fun(n - 1);
cout << n << endl;
}
}
int main()
{
int x = 5;
fun(x);
}
The above code prints 1 2 3 4 5 while from my understanding it should only print 1.
At every call of function fun() make a note of value of variable n and you can trace the output easily. When the recursive call to fun() return, the statements after it will be executed (w.r.t. function fun() it is cout << n << endl; statement). It work like this:
fun(5) --> First call : n is 5
5>0 : true
| fun(5-1) --> Recursive call 1 : n is 4
| 4>0 : true
| | fun(4-1) --> Recursive call 2 : n is 3
| | 3>0 : true
| | | fun(3-1) --> Recursive call 3 : n is 2
| | | 2>0 : true
| | | | fun(2-1) --> Recursive call 4 : n is 1
| | | | 1>0 : true
| | | | | fun(1-1) --> Recursive call 5 : n is 0
| | | | | 0>0 : false --> Return from call 5
| | | | |
| | | | Print n (n is 1) and return from call 4
| | | Print n (n is 2) and return from call 3
| | Print n (n is 3) and return from call 2
| Print n (n is 4) and return from call 1
Print n (n is 5) and return from first call to main()
Hence, the output is 1 2 3 4 5.
The key thing to recognize here is that the fun() recursive function prints the value after making the recursive call. So this is what is actually happening:
call fun(5) from main()
call fun(4) from fun()
call fun(3) from fun()
call fun(2) from fun()
call fun(1) from fun()
return from fun(0)
print 1
print 2
print 3
print 4
print 5
That is, the print statements happen the recursive calls, beginning with the value at the bottom of the recursion, which is 1, then backing out to 5.
Well, the key here is that the function will continue execution after the recursive call, so:
fun(n - 1);
cout << n << endl;
will call fun(n-1) and still continue the execution of cout << n << endl; after fun(n-1) returns. It doesn't just go away. It only postpones the execution of writing to cout until after the recursive call returns.
It is unclear to me what you wish to accomplish with this recursive function, but if you want to only print 1, you will need to encapsulate it in an if statement:
if(n == 1) {
cout << n << endl;
}
Or do something else to that effect. If that's not what you want, you may need to rewrite your recursive function completely (if you're not sure how to, you may need to ask another question explaining your needs more explicitly).
Follow the execution:
int x = 5;
fun(5); // Since x = 5
if (5 > 0) // Since n = 5
fun(4); // Since n - 1 = 4
if (4 > 0) // Since n = 4
fun(3); // Since n - 1 = 3
if (3 > 0) // As before...
fun(2);
if (2 > 0)
fun(1);
if (1 > 0)
fun(0);
if (0 > 0) // If fails, so function exits
cout << 1 << endl; // Then returns
cout << 2 << endl; // Then returns
cout << 3 << endl; // ...
cout << 4 << endl;
cout << 5 << endl;
I always write down the execution in the above format when I'm trying to understand some complicated algorithm. The method works both for newbies and more experienced programmers.
First, you should change the condition of end to (n >1) and then, you can have the result [2 3 4 5]. see here.
#include <iostream>
using namespace std;
void fun(int n)
{
if (n > 1) {
fun(n - 1);
cout << n << endl;
}
}
int main()
{
int x = 5;
fun(x);
}
Second, you can have the revese result [5 4 3 2 1] if you change the line position. see here.
#include <iostream>
using namespace std;
void fun(int n)
{
if (n > 0) {
cout << n << endl;
fun(n - 1);
}
}
int main()
{
int x = 5;
fun(x);
}
I think, rather than asking about this exact function. Please learn how recursion works. There are plenty of resources out there. You can also follow: https://www.geeksforgeeks.org/recursion/

the following problem is a multi threaded problem. i need to print the 'Done' in the next line without using '\n' or 'endl'

Q1. You will implement the function f(n) = n(n+a)(n-b) through multi-threading. The main thread will take three numbers n, a and b as input. There will be 4 additional threads. Main thread will pass the number n as parameter to the first thread and the second threads. The numbers a and b will not be passed as parameter to the first and the second threads. The first thread will calculate n(n+a) and print it (according to given sample). The second thread will use the n(n+a) value calculated by the first thread and calculate n(n+a)(n-b) and print the result (according to the given sample). The third thread will print “Done” after the above-mentioned outputs. The fourth thread will print necessary line breaks between outputs of other threads.
Sample input:
5
2
3
Sample output:
Result1 = 35
Result2 = 70
Done
My code:
#include<iostream>
#include<thread>
using namespace std;
int a ,b, temp;
void func1(int n)
{
cout << "Result_1 = ";
temp = n*(n+a);
cout << temp;
}
void func2(int n)
{
this_thread::sleep_for(chrono::milliseconds(10));
cout << "Result_2 = ";
cout << temp*(n-b);
}
void func3()
{
this_thread::sleep_for(chrono::milliseconds(50));
cout << "Done";
}
void func4()
{
//cout <<"New Line" << endl;
cout << endl;
}
int main()
{
int n = 5;
a = 2 , b = 3;
thread t1(func1,n);
t1.join();
thread t2(func2,n);
//this_thread::sleep_for(chrono::milliseconds(1000));
thread t3(func3);
thread t4(func4);
t2.join();
t3.join();
t4.join();
}
The above code outputs:
Result_1 = 35
Result_2 = 70Done
But I want:
Result_1 = 35
Result_2 = 70
Done

Values not written to vector

I'm trying to read pairs values from a file in the constructor of an object.
The file looks like this:
4
1 1
2 2
3 3
4 4
The first number is number of pairs to read.
In some of the lines the values seem to have been correctly written into the vector. In the next they are gone. I am totally confused
inline
BaseInterpolator::BaseInterpolator(std::string data_file_name)
{
std::ifstream in_file(data_file_name);
if (!in_file) {
std::cerr << "Can't open input file " << data_file_name << std::endl;
exit(EXIT_FAILURE);
}
size_t n;
in_file >> n;
xs_.reserve(n);
ys_.reserve(n);
size_t i = 0;
while(in_file >> xs_[i] >> ys_[i])
{
// this line prints correct values i.e. 1 1, 2 2, 3 3, 4 4
std::cout << xs_[i] << " " << ys_[i] << std::endl;
// this lines prints xs_.size() = 0
std::cout << "xs_.size() = " << xs_.size() << std::endl;
if(i + 1 < n)
i += 1;
else
break;
// this line prints 0 0, 0 0, 0 0
std::cout << xs_[i] << " " << ys_[i] << std::endl;
}
// this line prints correct values i.e. 4 4
std::cout << xs_[i] << " " << ys_[i] << std::endl;
// this lines prints xs_.size() = 0
std::cout << "xs_.size() = " << xs_.size() << std::endl;
}
The class is defined thus:
class BaseInterpolator
{
public:
~BaseInterpolator();
BaseInterpolator();
BaseInterpolator(std::vector<double> &xs, std::vector<double> &ys);
BaseInterpolator(std::string data_file_name);
virtual int interpolate(std::vector<double> &x, std::vector<double> &fx) = 0;
virtual int interpolate(std::string input_file_name,
std::string output_file_name) = 0;
protected:
std::vector<double> xs_;
std::vector<double> ys_;
};
You're experiencing undefined behaviour. It seems like it's half working, but that's twice as bad as not working at all.
The problem is this:
xs_.reserve(n);
ys_.reserve(n);
You are only reserving a size, not creating it.
Replace it by :
xs_.resize(n);
ys_.resize(n);
Now, xs[i] with i < n is actually valid.
If in doubt, use xs_.at(i) instead of xs_[i]. It performs an additional boundary check which saves you the trouble from debugging without knowing where to start.
You're using reserve(), which increases capacity (storage space), but does not increase the size of the vector (i.e. it does not add any objects into it). You should use resize() instead. This will take care of size() being 0.
You're printing the xs_[i] and ys_[i] after you increment i. It's natural those will be 0 (or perhaps a random value) - you haven't initialised them yet.
vector::reserve reserve space for further operation but don't change the size of the vector, you should use vector::resize.

How to get the stack to work in function calls?

Does stack come into the frame in the following code? If num=5. Why am i getting the output as zero..what about the numbers from 5 to 1?
void rec(int num)
{
cout << num << endl;
if( num > 0 )
return rec(num-1);
cout << "after" << num << endl;
}
does it include the concept of stack?
"Why am i getting the output as zero"
Look at the logic of you function. if(num>0) - return rec(num-1);.
So for every nubmer above 0, the function will just call itself again with num-1.
And only when num==0 you will get to this line
cout<<"after"<<num<<endl;
Meaning that for every number you will enter, the function will do nothing and call itself again with number-1 before the cout<<"after"<<num<<endl; line, and at the last time it will not call it self again (since num > 0 condition is false) and it will print 0.
If you want to see the "returned value", you could do something like this:
void rec(int num)
{
cout << num << endl;
if( num > 0 )
rec(num-1);
cout << "after" << num << endl;
}
The return rec(num-1); is technically valid, but since the function doesn't actually return soemthing, it's the same as writing:
if (num > 0)
{
rec(num-1);
return;
}