Difficulties in understanding this recursion - c++

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

Related

Does not iterate in recursion

I have made a code to solve a problem.
This is the link of problem: https://brilliant.org/practice/bijections-overview/?p=2
My opinion is use recursion. I have 3 elements to sum up 5, I iterate single element from 0 to 5 and so on.
This is my code:
#include<bits/stdc++.h>
using namespace std;
int count_sum_5(int sum, int n)
{
if(n == 1) return 1;
for(int i = 0; i <= sum ; i++){
return 1 + count_sum_5(sum - i, n - 1);
}
}
int main()
{
int sum = 5;
int count_ele = 3;
cout << count_sum_5(sum, count_ele);
}
Its output is 3, I think it only runs on i = 0 but does not run on i = 1, 2, 3, 4, 5. Could you help me?
Your function will return 1 if n is 1. Otherwise it will enter the for cycle, which will return the value of the first iteration. You call your function by passing 5 and 3, respectively.
First call: It returns 1 + count_sum_5(5, 2)
Second call: It returns 1 + count_sum_5(5, 1)
Third call: It returns 1
So, the second call will evaluate to 1 + 1 = 2 and then the second call will evaluate to 1 + 2 = 3. I'm not sure what your intention is, but the for cycle is not needed for your recursion. Your function is equivalent to
int count_sum_5(int sum, int n)
{
if(n == 1) return 1;
return 1 + count_sum_5(sum, n - 1);
}
I'm not sure whether you are satisfied with this. If not, then please let me know what you intend to achieve, sample inputs and outputs would help. If you provide further information, then I will edit my answer accordingly.
return evaluates 1 + count_sum_5(sum - i, n - 1) and then immediately exits the whole function, on the first iteration of the loop. It's not possible to return from a function multiple times.
I don't know what exactly are you trying to solve using that. But For loop will run only one time for i=0, because as soon as it evaluates the 1+count_sum(sum-i, n-1), It will return it.
However, you can do the following changes:
#include<bits/stdc++.h>
using namespace std;
int count_sum_5(int sum, int n)
{
if(n == 1) return 1;
int temp = 0;
for(int i = 0; i <= sum ; i++){
temp += (1 + count_sum_5(sum - i, n - 1));
}
return temp;
}
int main()
{
int sum = 5
int count_ele = 3;
cout << count_sum_5(sum, count_ele);
}

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)

Question regard to this recursion function

A code to find a factorial of an input n:
#include <iostream>
using namespace std;
long long factorial(int num) {
if (num == 0) {
return 1;
}
else {
return num * factorial(num-1);
}
}
int main() {
int num;
cin >> num;
cout << factorial(num) << endl;
}
My questions are:
Here written factorial(num-1) then how can the variable num get decreased per loop ? The function will permanent use num-1 as its argument but num is not saved. I mean there should be num--; in the function. I have tried and printed out variable num at the end of the program and it was the same, num wasnt 0.
Here written if (num == 0) { return 1; } . When num get decreased to 0 then shouldn't the function takes 1 as it final value ? But it doesn't. Just like variable, when you write a = 1 at the end of the program; then doesnt matter what calculation happened to a before, the final value of a will be 1. And as I understand return 1; has the same effect, doesnt it ?
Many thanks
Recursive functions work exactly like non-recursive functions - there is no "loop" and nothing gets decremented.
Perhaps the substitution method could help.
Consider factorial(2).
If we replace num with 2 in the function's body we get
if (2 == 0) {
return 1;
}
else {
return 2 * factorial(2-1);
}
In order to calculate this, we need factorial(1), which becomes
if (1 == 0) {
return 1;
}
else {
return 1 * factorial(1-1);
}
And now we need factorial(0):
if (0 == 0) {
return 1;
}
else {
return 0 * factorial(0-1);
}
This is clearly 1, so now we can move back up and insert the calculated values in place of the function calls.
factorial(1):
if (1 == 0) {
return 1;
}
else {
return 1 * 1;
}
which is 1, and then factorial(2):
if (2 == 0) {
return 1;
}
else {
return 2 * 1;
}
which is 2.
Note that there is no "connection" between the recursive calls - they don't share any variables or other data, their arguments just happen to have the same name - and return does not return to the "topmost" caller but only to the most immediate one, just like other functions.
The original variable "num" is never decreased there.
It's an integer, thus, is a value type. So, everytime by writing factorial(num-1) you create a new variable with the value (num-1) and pass it to the function. (e.g. if num was 5 then it would be like calling factorial(4))
Again, "num" never gets decrased. You just pass a new variable that has the num-1 value. So, in the previous loop when the num was 1, and you called factorial(num-1) you just passed it's like calling factorial(0), and here that 0 was just checked in the if statement and exited by returning 1.
Lets break this down with a concrete example. If you call factorial(5) then what happens is you run if (num == 0), which is false, so you then run return num * factorial(num-1);, where num is 5 so it's return 5 * factorial(4). Now, in order for return to return, it needs to evaluate factorial(4). Just like factorial(5), factorial(4) becomes return 4 * factorial(3), this happens for 3, 2 and 1. Once you are in factorial(1), you get return 1 * factorial(0), and factorial(0) passes if (num == 0), so it is just return 1.
Putting all that together you get
return 5 * 4 * 3 * 2 * 1 * 1

why am I getiing 0 as a result,I want the return value as the result?

I want the result to be the returned value from the mystery function,but the result is always 0 .but I want the program to return a value that's collected from the mystery function
#include <iostream>
using namespace std;
int Mystery(int n)
{
// int k;
if (n <= 1)
{
return 0;
}
else
{
int k = n;
for (int i = 1; i <= n; i++)
{
k = k + 5;
}
cout << ((k * (n / 2)) + (8 * (n / 4)));
cout << "\n ";
return ((k * Mystery(n / 2)) + (8 * Mystery(n / 4)));
}
}
int main(void)
{
int i, n;
cout << "Enter n:"; //array size
cin >> n;
int result = Mystery(n);
cout << "The result is " << result;
return 0;
}
Let's desk check what happens when you call Mystery(2). The final return value is:
((k* Mystery(n/2)) + (8* Mystery(n/4)))
We know that n == 2 so let's substitute that:
((k* Mystery(1)) + (8* Mystery(0 /* by integer division of 2/4 */)))
This will call the function recursively twice with the respective arguments 1 and 0. But we know that the terminating case n <= 1 returns 0, so we can substitute that:
((k* 0) + (8* 0))
Anything multiplied by zero is zero, so this reduces to 0 + 0 which is also zero. It doesn't even matter what k is.
Quite simply, the terminating case for this recursion mandates that the result is always zero.
In the terminating case the return value is zero.
In the recursive case, the recursive call result is multiplied with another value to produce the return value.
Therefore, the result is always going to be zero for any n.
I'm not sure exactly how this function is supposed to work as you have not explained that, but changing the terminating case to return 1; may solve the problem.
I don't expect which result you want, but I think you can get write result when you correct conditions like
if (n == 0)
return 0;
if (n == 1)
return 1;
I hope it returns the right result.

Explain the output of this program

I can't figure out how this works, the code is really complicated because it is for a programming class I'm in. I can't seem to get the program's output when I work it through manually, it is the practice test for our final next week, I wouldn't cheat on a test, the professor gave us the program and the output, I just don't understand why that is the output..:
class FinalExam
{
private:
int This;
int That;
public:
FinalExam(int, int);
void One(int);
int Two(int);
};
FinalExam :: FinalExam(int A = 3, int B = 5)
{
This = A;
That = B;
}
void FinalExam :: One(int A)
{
This --;
That = A;
}
int FinalExam :: Two(int A) // Two gets the int 8
{
int Scrap;
Scrap = This + That - A; // 5 + 2 - 8 = -1????
return Scrap;
}
main()
{
FinalExam Block;
FinalExam Chunk(6, 7);
Block.One(2);
cout << Block.Two(3)
<< '\n'
<< Chunk.Two(8); //I get lost on this 8, It should go to "Two"
}
And the output is:
1
5
I have looked at this for about an hour and I don't understand.
FinalExam Block; // Not passing any arguments to the constructor. In that case,
// default argument values are taken. So, This = 3, That = 5
Block.One (2); // This = 2; That = 2
// Because This is decremented and That is assigned the value
// passed to the method which is 2.
cout << Block.Two (3) ; // 2 + 2 - 3 = 1 which is returned and is printed.
Similarly try the second one.
Explanation of what's happening in the comments between the lines.
int main(int, char**) {
FinalExam Block;
// At this point ..
// Block.This = 3;
// Block.That = 5
FinalExam Chunk(6, 7);
// Chunk.This = 6
// Chunk.That = 7
Block.One(2);
// Block.One decrement's This and assigns 2 to That so ..
// Block.This = 2
// Block.That = 2
std::cout << Block.Two(3)
// Block.Two(3) returns the result of this calculation
// This + That - 3
// This and That are both 2 at this point so..
// 2 + 2 - 3 == 1
// It returns 1 and prints out '1'
<< std::endl
<< Chunk.Two(8);
// Chunk's This and That are 6 and 7 respectively so ..
// cout << 6 + 7 - 8 == 5
}
Here's a line-by-line breakdown:
1 FinalExam Block;
Uses the constructor with default values, so Block.This = 3, and Block.That = 5.
2 FinalExam Chunk(6, 7);
Uses the constructor, specifying values, so Chunk.This = 6 and Chunk.That = 7.
3 Block.One(2);
Decrements Block.This (3 ==> 2), and assigns Block.That = 2 (was previously 5).
4 Block.Two(3)
returns Block.This + Block.That-3 ==> 2+2-3 ==> 1, which is output.
5 Chunk.Two(8)
returns Chunk.This + Chunk.That - 8 ==> 6+7-8 ==> 5, which is output.
Q.E.D. the output is "1 \n 5"
Firstly, you'll notice that we're creating two objects of type FinalExam called Block and Chunk.
Block:
since block wasn't passed any values via the parameter, it will take on the default values which come from this code block:
FinalExam :: FinalExam(int A = 3, int B = 5)
{
This = A;
That = B;
}
so This = 3 and That = 5
The next line that effects Block is:
Block.One(2);
which refers to this code block:
void FinalExam :: One(int A)
{
This --;
That = A;
}
so This = 2 (This = This - 1 or This = 3 - 1)
and That = 2 (That = A = 2(passed by value in parameters)
The last line effecting Block is:
cout << Block.Two(3)
which refers to this code block:
int FinalExam :: Two(int A) // Two gets the int 8
{
int Scrap;
Scrap = This + That - A; // 5 + 2 - 8 = -1????
return Scrap;
}
so we create a new integer called Scrap = 1 (This + That - A or 2 + 2 - 3(passed by value))
Chunk:
the first line that refers to Chunk is:
FinalExam Chunk(6, 7);
this set A = 6 and B = 7
and because of this code block:
FinalExam :: FinalExam(int A = 3, int B = 5)
{
This = A;
That = B;
}
This = 6 and That = 7 (This = A = 6 and That = B = 7)
and finally, we have this line:
Chunk.Two(8);
which refers to this code block:
int FinalExam :: Two(int A) // Two gets the int 8
{
int Scrap;
Scrap = This + That - A; // 5 + 2 - 8 = -1????
return Scrap;
}
A is set to 8 since we passed it by value through parameters
and Scrap = 5 (b + 7 - 8 or This + That - A)
Output:
We output Scrap from Block which is 1
and create a new line
and output Scrap from Chunk which is 5
Hope this helps, leave a comment if you have any additional questions