Big Theta (Θ) runtime of recursive functions - c++

I'm having trouble trying to understand the runtime. Any help would be much appreciated!
int foo(int x) {
if (x <= 0) return x;
cout << x;
return foo (x-1);
}
void bar(int n) {
if (n <= 0) return;
cout << foo (n) << endl;
bar (n-1);
cout << n;
}
int main() {
int n;
cin >> n;
bar(n);
return 0;
}

Foo is printing the number you passes and it will do x-- until is 0, if you pass 5 it will print 543210, so you can called it decrement n by 1 and print the result
Bar is doing the same without printing, only decrementing and calling foo
It is a 3 recursion level, try to use a small number and follow the flow, like 4
-Bar gets 4, the case base it is 0, 4 is greater than 0 so it will continue, it will call foo(4) (remenber that foo is a recursive call that will print 4 to 0 => 43210, decrementing the number by 1 each time)
-And bar gets called again, this time with n-1 = 4 -1 = 3, with the value 3, it will call foo(3) and the same
When you meet the case base in bar, n == 0 you will stop calling anothers functions and this function will get the value returned, you can print on screnn but it doesnt mean that the function ends, it was waiting for the other values to return, when it returns it prints the n that called it, so it will be 1234, that is it that the values 1, 2, 3 and 4 are the values that enter bars one at a time and prints the value of the result of foo (for 4,3,2,1) because it is what you get
int foo(int x) { //Decrementing by one and printing the value
// If x reaches 0 exit (you need an exit in a recursion)
if (x <= 0) return x;
// Print the value x (the first time x will be the n, the second n-1)
cout << x;
// Call the same function in we are but with x-1 value
return foo (x-1);
}
// It will produce foo(4)=>foo(3)=>foo(2)=>foo(1) and foo(0)
// foo(0) will break the recursion and finish here (only prints)
// It is where main calls and enters n is the value you type
void bar(int n) {
// Case base to break recursion when it reaches 0
if (n <= 0) return;
// Here is the code that prints the line that foo will make
cout << foo (n) << endl;
// Here you will call the same function but with n-1, like foo does
bar (n-1);
// When all the recursion above is over you will get here
// In the stack you will have done n calls into here with n-x
// So every one will print the value of n that in the paremeter
// when the call was make
cout << n;
}

Related

Changing function argument to global variable causes unexpected results

I'm solving a backtracking problem. I have to construct a permutation of length n in such a way that the sum of each adjacent elements are prime. The permutation is circular, the last element is adjacent to first element. Note that all valid permutations should start with 1.
void recurse(int i, int prev, int n, vector<int> prime_ring) {
if (i == n) {
prime_ring.insert(prime_ring.begin(), 1);
if (!is_prime[prime_ring.back() + 1])
return;
for (auto data : prime_ring)
cout << data << " ";
cout << "\n";
prime_ring.clear();
return;
}
for (int next = 2; next <= n; next++) {
if (!seen[next] && is_prime[prev + next]) {
prime_ring.push_back(next);
seen[next] = true;
recurse(i + 1, next, n, prime_ring);
seen[next] = false;
prime_ring.pop_back();
}
}
}
The above code generates the wanted permutations correctly. For example for n = 4. Permutations should be
1 2 3 4
1 4 3 2
void recurse(int i, int prev, int n) {
if (i == n) {
prime_ring.insert(prime_ring.begin(), 1);
if (!is_prime[prime_ring.back() + 1])
return;
for (auto data : prime_ring)
cout << data << " ";
cout << "\n";
prime_ring.clear();
return;
}
for (int next = 2; next <= n; next++) {
if (!seen[next] && is_prime[prev + next]) {
prime_ring.push_back(next);
seen[next] = true;
recurse(i + 1, next, n);
seen[next] = false;
prime_ring.pop_back();
}
}
}
Changing prime_ring to a global vector, results in runtime error. This problem happened to me many times, I failed to realise what's wrong. I'm not aware of the difference between global vector vs function argument vector.
I'm not aware of the difference between global vector vs function argument vector.
The difference is that when you pass a vector as a parameter, the vector is copied. On the other hand when you use a global variable, there is only one `vector.
The solution here is to not use a global variable since you have a working function.
Suppose you are on the line
recurse(i + 1, next, n);
where i == n - 1
Suppose when you go into the recurse function, is_prime[prime_ring.back() + 1] is true.
Then you call prime_ring.clear();, and returns.
Afterwards, you call prime_ring.pop_back();
What happens if you try to pop_back() from an empty vector? Well, bad things can happen (namely, Undefined Behaviour)

is it possible to explain why this returns 21

Hello this isn't an assignment or anything but can you explain why this returns 2 1.
#include <string>
using namespace std;
void fun(int);
int main()
{
int a = 0;
fun(a);
return 0;
}
void fun(int n)
{
if (n < 2)
{
fun(++n);
cout << n<<" ";
}
}
Flow of fun() :
You are passing a which is initialized to 0 as the parameter to the fun(). So, You call fun(0) from main().
In the call fun(0) the condition n<2 is true since at the start, it is 0. So the function fun(0) will
call fun(++n),that is fun(1) and push the current function call on the stack. Notice, the value of n in the function call which is pushed has increased to 1.
Again, n<2 evaluates to true since now the value of n is 1. The
function will call fun(++n) again, that is fun(2) and push the current function call to stack once again.Notice, the value of n in the function call which is pushed has increased to 2.
Now, the value of n is 2 and hence n<2 evaluates to false. So,
this time it will not do anything and just terminate
Now, the last function call will get popped from stack and cout will get executed. So, the control returns to the function at the top of the stack, which in our case is fun(1). But, here we had increased our n by doing ++n (Check point : 3). So the value printed will be 2. This function call now gets terminated.
Now, at the top of stack is the function call that we pushed at first, that is fun(0) but our value of n was increased by ++n (Check point : 2). So now the value of n which is 1 will be printed.
Hope you understand the above explanation and this solves your doubt !
You can think about recursion as nesting the functions inside of each other.
You pass n = 0.
fun(n=0)
{
if (0 < 2)
{
// ++n alters n to be equal to n+1 for our current scope.
fun(++n); // n = 1 now, fun gets called with n = 1
{
fun(n=1)
{
if (1 < 2)
{
fun(++n); // n = 2 now, fun gets called with n = 2
{
fun(2)
{
if(2 < 2) // returns false
}
} // we exit this scope without doing anything futher
cout << n << " "; // n = 2 in this scope, here we print the 2
}
}
} // now we exit this scope
cout << n<<" "; // n = 1 in this scope, here we print the 1
}
}
Please let me know how I can clarify this further.
This code does not return anything, except for the main function that returns 0 exit code. The function fun just prints.
It prints 2 1, because it computes this:
void fun0()
{
fun1();
cout << 1 <<" ";
}
void fun1()
{
cout << 2 <<" ";
}
Therefore it first prints 2 and then prints 1 after the code returns from fun1.
Every time you make a recursive call a new instance of n will be created. The program will only reach the first cout after two recursive calls, so n will be 2 at that point. I don't want to explain how everything works in detail, I genuinely think that if you write some more printf's you will be able to figure out what the program is doing by yourself. If you figure this out by yourself with my simple hints you'll know how recursion works pretty well.
fun() is a non tail recursion call and base condition is n<2 then
fun will call twice fun(0) &fun(1). As recursion activation record maintain on stack then while reaching at base condition it will print
2 1
Cout "2"
Cout "1"
I will recommend please go through recursion concept thoroughly.
Firstly function will not return anything until you add a return statement in the function, In your case you are not returning the value, you wrote a statement to print/display the current value of 'n' initially you set a=0 and calling a function "fun(a)" and passing the value of "a" So, in the "fun" function you added a condition which says the value of "n" should be smaller than "2", then you are using the recursive method(a function that calls itself) and pre incrementing "++n" the value of "n" and passing it in the fun function.
n = 0
fun(n)
fun(0){
if (n < 2) *first call true
{
fun(++n); *n = 1 before going to next condition it is calling itself*
cout << 1<<" ";
}
}
fun(1){
if (n < 2) *true*
{
fun(++n); *n = 2 again before going to next condition it is calling itself*
cout << 2<<" ";
}
}
fun(2){
if (n < 2) *flase*
{
fun(++n);
cout << n<<" ";
}
}
So, it will print 2 and then 1.
flow of Recursive function
I hope you get your answer.

Difficulties in understanding this recursion

I don't get this recursion exercise in C++. Here it is:
int fatt(int x){
int s=1; // here. since 's' will always be 1 shouldn't i get 1 as an output???
if(x>1) { s = x*fatt(x-1); }
return s;
}
int main()
{
int n;
cout << "Type a number: ";
cin >> n;
if (n < 0) { cout << "Error" << endl; }
if (n <=1) { cout << "Factorial: 1" << endl; }
else { cout << "Factorial: " << fatt(n) << endl; }
}
If I put s=0 it returns me as an output always 0, if I put 2 it doubles the result O.o I don't get how it works. I understand that x is always getting diminished until reaches 2 and the returns the result but everytime the function is called shouldn't 's' be given the value of 1???
Say you call the function with the parameter value 3: It would look like this:
int fatt(3) {
int s = 1;
if (3 > 1) s = 3 * fatt(3 - 1);
return s;
}
So s is the result of the calulation 3 * fatt(2) and the result of fatt(2) is:
int fatt(2) {
int s = 1;
if (2 > 1) s = 2 * fatt(2 - 1);
return s;
}
So s is the result of the calculations 2 * fatt(1) and the result of fatt(1) is:
int fatt(1) {
int s = 1;
if (1 > 1) s = 1 * fatt(1 - 1); // False so this is never executed.
return s;
}
The result of fatt(1) is 1. So that is what we return to the call of fatt(2) which then translates to:
s = 2 * 1;
Which gives the result 2 which is then returned to the call of fatt(3) which then gives:
s = 3 * 2;
Which gives the result 6.
Remember that the local variable s is pushed on the stack each time the function is executed. So it is not the same variable.
If you initiated s to 2, then the first line would read: s = 2 * 2; and the rest of the function would give double the value in result. Since s is really a factor that you end up multiplying with, in your factorial:
So the sequence: 3 * 2 * 1 becomes 3 * 2 * 2.
The variable s is local to the given instantiation of the function fatt. As the function recursively calls itself, every invocation gets its own new copy of s. This is initialised to 1, but doesn't affect all the previous s instances lower down in the stack. Each one of those is then assigned to the result of the fatt invocation mediately after it multiplied by its local copy of x.
's' should be 1 but it gets assigned and then changes the value it holds upon the completion of a function.
Recursions can be a bit hard to understand at first but once you do, it's beautiful.
I suggest you use a pen and paper.
1) Let x = 3;
int fatt(3) {
int s = 1;
if (3 > 1) s = 3 * fatt(3 - 1);
return s;}
2) In the function 3>1 = true so it gets passed on again but this time as (3-1) i.e 2
Note: function isn't done executing
3) Now x = 2
int fatt(2) {
int s = 1;
if (2 > 1) s = 2 * fatt(2 - 1);
return s;}
4) Repeat step 2) (2-1) i.e 1
5) Since x IS NOT > 1 in the 3rd function call this results in the returning of s
s = 1;
return s;
So...
Starting at the 2rd function call:
s = x * fatt(x-1);
s = 2 * 1;
return s;
Repeat this again for the first call)
s = x * fatt(x-1);
s = 3 * 2;
return s;
Think of it like a stack of functions
1st stack ------- calls stack 2 and waits
2nd stack ---------- calls stack 3 and waits
1st stack ---------- waiting
Finally...
3rd stack ---------- condition not met return
2nd stack ---------- condition done return
1st stack --------- condition done return
Hope that helps

Recursive coin change c++

My program seems to be crashing every time it recursive calling in the minimum function. Can anyone tell me why it is crashing. It would instantly freeze after i call the minimum function. Is it because im using a vector?
#include <iostream>
#include <vector>
#include <math.h>
#include <algorithm>
using namespace std;
int minimum(vector<int> denom, int s, int N) //take in denomination , sizeofcoin, and value of N
{
if(N == 0)
{
return 1;
}
else if(N < 0 || (N > 0 && s <=0))
{
return 0;
}
else
{
return min(minimum(denom,s - 1, N), 1 + minimum(denom, s,N-denom[s-1]));
}
}
int main()
{
int N;
unsigned int sizeofcoin;
cout << "Enter the value N to produce: " << endl;
cin >> N;
cout << "Enter the number of different denominations: " << endl;
cin >> sizeofcoin;
vector<int> denom(sizeofcoin);
for(unsigned int i= 0; i < sizeofcoin; i++)
{
cout << "Enter denomination #" << (i+1) << endl; //save all the denominations in an array
cin >> denom[i];
}
sort(denom.begin() , denom.end(),greater<int>()); //sort the array from largest to smallest
if(denom.back() != 1) //check the end of the array (since the back is smallest now) if it has 1
{
denom.push_back(1); //Will include 1 if the user does not input a 1 (doesn't have to be used)
}
minimum(denom,sizeofcoin,N);
return 0;
}
I tried to explain your minimum() function to your rubber duck, and your rubber duck has a question for you. Here's how our conversation went:
int minimum(vector<int> denom, int s, int N) //take in denomination , sizeofcoin, and value of N
{
if(N <= 0)
{
return 0;
}
Me: this minimum() recursive function immediately returns if its third parameter, N, is 0, or negative.
Your Rubber Duck: Ok.
return (minimum(denom,s - 1, N)...
(Here, I tried explaining your first recursion call here, to your rubber duck):
Me: So, this makes a recursive call, with the same parameters, except that the 2nd parameter is decremented. The third parameter is N.
Your Rubber Duck: So, if the third parameter's value, N, is unchanged, and the recursive function returns without recursing only when N is 0 or negative, and the initial call to minimum() passes a value greater than 0 for N, then when exactly do you expect this recursion to stop?
I couldn't answer this question myself, maybe you can explain this to your rubber duck, by yourself. When does recursion stop, here?
You have the recursive call minimum(denom,s - 1, N) so N will never be less than or equal to 0, and the recursion will never end.
This would have been very easy to find out if you learned how to use a debugger, and stepped through the code line by line, and stepped into the recursive calls.
Another thing that I want to point out is that you are trying to return the sum of two values:
(minimum(denom,s - 1, N) + minimum(denom, s,N-denom[s-1])
instead what you should do is:
min(minimum(denom,s - 1, N), 1 + minimum(denom, s,N-denom[s-1]))
The idea is that in first call you've not used any coin but in second call you have used one, so adding 1 for the same.
Look for a Dynamic Programming solution for the same.
https://people.cs.clemson.edu/~bcdean/dp_practice/

C++ recursion example explanation

I have the following code example and I cannot figure out why it displays 123.
Since these are integers I understand the decimals are not displayed. But I expected it to show 3, 2(.3), 1(.23) (in the opposite order). When n goes below 10 everything stops after the final cout... right?
#include <iostream>
using namespace std;
void recursion(int n) {
if (n < 10) cout << n;
else {
recursion(n / 10);
cout << n % 10;
}
}
int main() {
recursion(123);
return 0;
}
Well, you call with 123 as n, the function executes the statement:
if (n < 10) // its false, so it continues with else:
else {
recursion ( n /10 ) // recursive call n/10 = 123/10 = 12 (as it's int)
...
It will continue like this, recursively calling with n being 12
recursion (n/10) // second recursion call n=12, so n/10 = 1
then the function is executed, with n being 1 so smaller than 10
if (n < 10) // its true
cout << n; // 1 gets printed
else // no, the rest is skiped
...
then it returns from recursion. So we're back in the context where n was 12. The next statement to be executed in that context is :
cout << n %10; // prints 12 % 10, which is 2
then, continuing like this, similarly it will print 123%10, which is 3. In conclusion, the 123 that is printed has nothing to do with the 123 entered as input.
I think you wanted to do :
...
else {
cout << n % 10; // first print to see the count down
recursion(n / 10); // then recurse
}
But you have to learn using a debugger. As long as you don't, put some extra cout to visualize what's happening.