I feel a little dumb asking this, but here we go...
When trying to follow the Recursion example at the following website http://www.cplusplus.com/doc/tutorial/functions2/, I ran into a road bump that has me perplexed.
I altered the code slightly just to get my head around the code in the recursion example and I pretty much have my head around it, but I can't figure out why the variable 'n' increments in 'Pass B' when I have not told the program to increment 'n'.
Could you please help explain this?
#include <stdlib.h>
#include <iostream>
using namespace std;
long factorial (long n)
{
if (n > 1)
{
long r(0);
cout << "Pass A" << endl;
cout << "n = " << n << endl;
cout << "r = " << r << endl;
r = n * factorial (n-1);
cout << "Pass B" << endl;
cout << "n = " << n << endl;
cout << "r = " << r << endl;
return (r);
}
else
return (1);
}
int main ()
{
long number;
cout << "Please type a number: ";
cin >> number;
cout << number << "! = " << factorial (number) << endl;
system ("pause");
return 0;
}
That's because you are unrolling the recursion.
You are not really incrementing n you are just returning to previous function call where n was n+1 before you called factorial(n-1) ...
When you start you go up to
r = n * factorial (n-1);
which will cause another function call to the factorial.
You keep doing that (start from beginning of your function and go up to the call to factorial with n decremented by 1) until you eventually end up in a function call to factorial where n<=1.
In which case you return 1, but you return to previous call of factorial where n was 2, you do the multiplication (n * whatever was returned by factorial) and you finish the B path of that call and return r.
But you again return to the previous function call where you do the multiplication part and finish the B path and so on ...
factorial(5)
factorial(4)
factorial(3)
factorial(2)
factorial(1)
return 1
return r
return r
return r
return r
You see all "Pass A"-s in order and then all "Pass B"-s in reverse order which gives the impression that n increments eventhough you only see the originally passed n's.
It seems to me that your program works correctly and should output something like this for number=3 (Line breaks removed for readability):
Pass A n=3 r=0 [1]
Pass A n=2 r=0 [2]
Pass B n=2 r=2 [3]
Pass B n=3 r=6 [4]
So I think I can see how you would conclude that the n is incrementing in pass B but this in fact not the case.
You need to keep in mind that n is a function local variable so in this case the n printed in [3] is a DIFFERENT instance of the local variable to the n in [4].
The values of n printed in [1] and [4] are from the top call of the function (where n=3), the values printed in [2] and [3] are the call in the top version of factor (i.e n-1).
If you notice, Pass B is not really passing through the function the second time, it only print the results of the recursion.
So A print 4, 3, 2, etc, while backwords B prints 4 3 2 1 (ie 2 3 4)
Please type a number: 4
Pass A
n = 4
r = 0
Pass A
n = 3
r = 0
Pass A
n = 2
r = 0
Pass B
n = 2
r = 2
Pass B
n = 3
r = 6
Pass B
n = 4
r = 24
4! = 24
Press any key to continue . . .
Try replacing the second r prints as
cout << "Pass B" << endl;
cout << "n = " << n << endl;
cout << "r = " << r << " --- NOTICE RESULT ACCUMULATING AS WE UNNEST THE RECURSION" <<endl;
PS C:\temp> .\r.exe 4
Please type a number: 4
Pass A
n = 4
r = 0
Pass A
n = 3
r = 0
Pass A
n = 2
r = 0
Pass B
n = 2
r = 2 --- NOTICE RESULT ACCUMULATING
Pass B
n = 3
r = 6 --- NOTICE RESULT ACCUMULATING
Pass B
n = 4
r = 24 --- NOTICE RESULT ACCUMULATING
4! = 24
Press any key to continue . . .
Pass B is printed when it is "unwinding" the recursion. It recursed until it hit the "else return (1);" part and then started backing out. Because it called itself with one less for n each time on the way in, it appears to be incrementing as it backs out.
The value of n in pass A and pass B will always be the same as you are not changing it anywhere in between. You pass n-1 to a recursive call but that does not change the value of n.
The reason why you might be confused is that you don't see pass A and pass B for a given n (n>2) next to each other.
When n=2, you'll see:
pass A for n=2
pass B for n=2
When n=3, you'll see:
pass A for n=3
pass A for n=2 // cuz of recursive call.
pass B for n=2
pass B for n=3 // looks like n has increment here..but this 'pass B' pairs with first pass A
Because that's when the recursion rewinds.
Maybe it would be easier to think about the case when n is 2. In that case you enter the conditional block and recurse after "Pass A". When you recurse n is 1, and so you return through the else block. When you return you are back at the previous frame of the recursion, where n is 2. r gets updated according to the result of the recursion call, 2*1, but n remains 2 as in the previous frame.
factorial(2)
factorial(1)
factorial(2)
If n would be initially any larger value then you'd keep rewinding, and n would restore its value to each value it had prior to each recursion.
factorial(3)
factorial(2)
factorial(1) // returns 1
factorial(2) // r=2*1
factorial(3) // r=3*2
Some of the answers use indentation to make it easier to understand what's happening - you case use the same effect to make your own debug output more comprehensible:
Try and change your function to something like this:
long factorial (long n, std::string prefix= "") // default parameter
...
cout prefix << "Pass A" << endl;
cout prefix << "n = " << n << endl;
cout prefix << "r = " << r << endl;
r = n * factorial (n-1, prefix+ " "); // increase indentation
...etc...
My use of std::string may be a bit flaky, but you'll get the idea. Your output should now look like this.
Please type a number: 4
Pass A
n = 4
r = 0
Pass A
n = 3
r = 0
Pass A
n = 2
r = 0
Pass B
n = 2
r = 2
Pass B
n = 3
r = 6
Pass B
n = 4
r = 24
4! = 24
Related
I'm currently taking a class for c++ and we are learning about recursion and in class my professor used this function as an example of recursion, the function is meant to return the smallest digit in a number and is:
int smallD(int n) {
if (n < 10) return n;
int x = smallD(n / 10);
if (x < n % 10) return x;
else return n % 10;
}
I'm confused on how setting x to the recursive call works, would the function not keep running n / 10 until n is < 10, I just really don't understand the concept and could use some pointers as to how this function works.
Here's something that helps to understand recursion. Add print statements to observe the code as it recursively calls itself and pass and "indent level" to help as well.
Take the original minified code and expand it to something more readable and add extra debugging information to it.
int smallD(int n, const std::string& indent) {
cout << indent << "enter: smallD(n=" << n << ")" << endl;
if (n < 10) {
cout << indent << "n < 10 => returning: " << n << endl;
return n;
}
cout << indent << "about to recurse inovking smallD(" << n / 10 << ")" << endl;
int x = smallD(n / 10, indent+" "); // grow the indent by 2 spaces
cout << indent << "return from recursion, result is: " << x << endl;
cout << indent << "x=" << x << " n=" << n << " n%10=" << n % 10 << endl;
if (x < n % 10) {
cout << indent << "x is less than n%10, returning: " << x << endl;
return x;
}
cout << indent << "x is greater than or equal n%10, returning: " << n%10 << endl;
return n % 10;
}
Let's try it out by invoking smallD(8942468, "")
enter: smallD(n=8942468)
about to recurse inovking smallD(894246)
enter: smallD(n=894246)
about to recurse inovking smallD(89424)
enter: smallD(n=89424)
about to recurse inovking smallD(8942)
enter: smallD(n=8942)
about to recurse inovking smallD(894)
enter: smallD(n=894)
about to recurse inovking smallD(89)
enter: smallD(n=89)
about to recurse inovking smallD(8)
enter: smallD(n=8)
n < 10 => returning: 8
return from recursion, result is: 8
x=8 n=89 n%10=9
x is less than n%10, returning: 8
return from recursion, result is: 8
x=8 n=894 n%10=4
x is greater than or equal n%10, returning: 4
return from recursion, result is: 4
x=4 n=8942 n%10=2
x is greater than or equal n%10, returning: 2
return from recursion, result is: 2
x=2 n=89424 n%10=4
x is less than n%10, returning: 2
return from recursion, result is: 2
x=2 n=894246 n%10=6
x is less than n%10, returning: 2
return from recursion, result is: 2
x=2 n=8942468 n%10=8
x is less than n%10, returning: 2 // <== this is the final result
So hopefully, that will help you understand how the recursion works.
Recursive functions work exactly like non-recursive functions.
One common mistake is to try to think about all the recursive calls at once, as if they had a shared state, but one key ingredient to understanding a recursive function is actually to ignore the recursion and just "think locally".
Perhaps working through an example would clarify things.
Let's look at smallD(321), replacing n in the body of the function with its value.
smallD(321)
if (321 < 10) return 321;
int x = smallD(321 / 10);
if (x < 321 % 10) return x;
else return 321 % 10;
The first condition is clearly false, and in order to determine x, we need smallD(321/10), which is smallD(32).
smallD(32)
if (32 < 10) return 32;
int x = smallD(32 / 10);
if (x < 32 % 10) return x;
else return 32 % 10;
The first condition is false again, so we keep going with smallD(32/10).
smallD(3)
if (3 < 10) return 3;
int x = smallD(3 / 10);
if (x < 3 % 10) return x;
else return 3 % 10;
Now the first condition is true, so the result here is clearly 3.
Now we can go back and use the value of x in each call that was left waiting.
smallD(32)
...
if (3 < 32 % 10) return 3;
else return 32 % 10;
And 3 < 32 % 10 is false, so we return 32 % 10 - 2 to the caller.
smallD(321)
...
if (2 < 321 % 10) return 2;
else return 321 % 10;
And 2 < 321 % 10 is false, so we return 321 % 10, which is 1.
Your intuition is not completely off: The function does indeed "keep running n/10 until n is <10" - but it's in different calls to the same function.
Your program keeps a stack of functions calls. Each function you call puts a (so-called) "frame" on top of everything that is currently on the stack. Inside that frame "live" all the variables "belonging" to that function call. When the function exits, it deletes its own frame from the stack. The currently executing function's frame is on the top of the stack. So, let's see what happens if you call smallD(123):
You start with something else on the stack, at least your main(). Your call to smallD(123) puts the frame for smallD(123) on the top of the stack. This frame contains the variable n = 123. Lets call this frame stack frame A.
Since n >= 10, your smallD(123) calls smallD(123 / 10), i.e., smallD(12) (integer division basically truncates in C++). So, you put another frame on top of your stack. This stack frame corresponds to smallD(12) and contains the variable n = 12. Let's call this stack frame B.
Again, n >=10, so the call to smallD(12 / 10) (i.e., smallD(1)) happens. A stack frame (call it C) is created for this new call, with n = 1.
Now n < 10 holds! The last function call (in stack frame C) returns the value 1 and deletes its own stack frame (frame C).
Stack frame B (where n = 12) is now on top and execution of smallD(12) continues. Since stack frame C has returned 1, stack frame B now contains x = 1. The comparison (x < n % 10) is true (1 < 2), and stack frame B return x = 1.
The same happens in stack frame A again, and stack frame A (which corresponds to our original smallD(123) call) returns 1.
So you see, indeed "division until n < 10" happened, but in different (recursive!) calls to smallD.
You can break down almost every recursive call into the base case (the simplest) and the recursive case. In this case:
The base case is when the number has only one digit: this means that is lesser than 10 (which is the first number with two digits).
if (n < 10) return n;
There is no other digit to compare it to, so return it directly.
The recursive case is any other case that is not the base. Now our digit has two or more digits, so:
And learn what is the smallest digit of all the digits except the last one with the recursive call x = smallD(n / 10)
Then we compare the result to the last digit, which we didn't include before, and return the smallest.
To understand better the process behind the calls, you could print some information and observe it. Try something like this:
int smallD(int n) {
if (n < 10){
std::cout << "Base case. Return " << n << std::endl;
return n;
}
std::cout << "Recursive case: " << n << std::endl;
std::cout << "Compare " << n % 10 << " with smallest of " << n/10 << std::endl;
int x = smallD(n / 10);
int ret;
if (x < n % 10) ret = x;
else ret = n % 10;
std::cout << "Smallest of " << n << " is " << ret << std::endl;
return ret;
}
I am just learning recursion and I am confused about the output of this recursive function.
int Run(int x)
{
if (x > 0)
cout << Run(x - 1) << " ";
return x;
}
If I call this function with Run(5), I get the output: 0 1 2 3 4
I expected to get the output: 0 1 2 3 4 5.
I'm confused as to why 5 is not returned at the end of the output. It's the value I plugged in to the function, so after all the recursive calls are made, shouldn't the function be returning that same value I plugged in?
Run does return 5, but the recursive calls to Run never do, and only the return of the recursive calls are printed.
Think about it like this: you aren't printing every x given to Run; you're only printing the return of the recursive calls. Your first call to Run that makes the recursive calls returns the 5 that you're expecting to be printed.
Basically, the 0 index means that your function will be executed n times, where n = the argument integer plus 1. the thing is the cout << Run(x - 1) << " "; will be executed n-1 times. This is because the first function call, once it executed all the other recursive calls, will return its value of x. but since it is not returning it to a previous recursive call which would then cout that value, it is not being displayed.
try this cout << Run(int x) on your main function.
We can see that Run(n) is a function that prints the non-negative whole numbers less than n and returns n. This means that for Run(n) you will get an output of 0 1 2 ... n-1 if n is positive.
What you have here:
cout << Run(x - 1) << " ";
is the same as
int r = Run(x - 1);
cout << r << " ";
That is, Run(x-1) will print the numbers less than x-1 and return x-1. So if x == 5 that means Run(x-1) printed the numbers from 0 to x-2 and r was set to 4. Then the function will print r and return. If you're still confused, it's also exactly the same as doing:
Run(x - 1);
cout << x-1 << " ";
Since we know that Run(x-1) will always return x-1 we can skip storing it in a variable and print it directly. A trick when analysing recursive functions is just to assume that they work - assume that Run(x-1) successfully prints the numbers from 0 to x-2 - the only thing left to do then is to print x-1.
So as you can see, the variable x never gets printed, only the numbers less than it. The function returns 5 but it just never prints it.
If you want it to print the non-negative whole numbers less than or equal to x, make this modification:
int Run(int x) {
if (x >= 0) {
cout << Run(x-1)+1 << " ";
}
return x;
}
The if statement has been changed to include 0 being printed now. Run(x-1) prints the numbers from 0 to x-1 and returns x-1, so adding 1 to the result allows us to print x.
I'm trying to figure out this C++ code line by line.
Can anyone explain it for me? Why is the output 1?
int main() {
int sum = 0;
for (int i=0; i<10; i++)
if (sum%2==0)
sum += i;
else
continue;
cout << sum << endl;
}
The code can be roughly translated to the English:
Start with a sum of zero then, for every number from 0 to 9 inclusive, add it to the sum if and only if the current sum is even.
So, you'll add zero to the sum (because the sum is currently even) after which the sum will still be zero (hence even).
Then you'll add one to the sum (because the sum is currently even) after which the sum will be one (hence odd).
Then you'll never add anything to the sum again (because it's odd and will remain so because you're not adding anything to it).
That's why it outputs one.
You may find it more instructive to simply modify your program to output what it's "thinking". The following changes will hopefully make it easier to understand:
#include <iostream>
using namespace std;
int main(void) {
int sum = 0;
for (int i = 0; i < 10; i++) {
cout << "Processing " << i
<< ", sum is " << sum
<< ((sum % 2 == 0) ? " (even):" : " (odd): ");
if (sum % 2 == 0) {
sum += i;
cout << "adding " << i << " to get " << sum;
} else {
cout << "leaving at " << sum;
}
cout << '\n';
}
cout << "Final value is " << sum << '\n';
}
Running that code will show you the steps along the way:
Processing 0, sum is 0 (even): adding 0 to get 0
Processing 1, sum is 0 (even): adding 1 to get 1
Processing 2, sum is 1 (odd): leaving at 1
Processing 3, sum is 1 (odd): leaving at 1
Processing 4, sum is 1 (odd): leaving at 1
Processing 5, sum is 1 (odd): leaving at 1
Processing 6, sum is 1 (odd): leaving at 1
Processing 7, sum is 1 (odd): leaving at 1
Processing 8, sum is 1 (odd): leaving at 1
Processing 9, sum is 1 (odd): leaving at 1
Final value is 1
I created a table trying to simulate the debug steps for you to understand the logic of your code and see why the result is evaluated to 1
Recommendation: learn how to debug. Depending on the IDE you are using they approach code debugging differently. Debug come in handy when you want to understand how your code is being executed.
About your code:
Try to use curly braces when possible, this helps your code to be clean and more understandable;
else continue: you don't need this line of code because there's nothing to skip in your loop after else condition;
Exchanging the comparison from
if (sum%2==0)
to
if (i%2==0)
would make sense.
This would sum up the even numbers 0+2+4+6+8 -> 20.
I have this function:
void m(int n)
{
if(n > 0)
m(--n);
cout << n << " "; //for n = 5 --> output is: 0 0 1 2 3 4
}
I have a problem with understanding how it works.
For example:
n(input) = 5
output: 0 0 1 2 3 4
My question is: Why does it show zero twice?
When I add brackets like this:
void m(int n)
{
if(n > 0)
{
m(--n);
cout << n << " "; // now, it shows 0 1 2 3 4 (n = 5)
}
}
So, what brackets cause in this code, that "0" exists only once?
And when I change pre-decrement (--n) to post-decrement (n--) it shows nothing. Why?
Could somebody help me to understand how it works?
First thing to note is : in C++ if you don't put brackets after an if statement, only the next line will be in the statement.
Example :
if(x > 0)
cout << 1;
cout << 2;
Here cout << 2 will always be executed no matter the value of x
The correct way of writing this is
if(x > 0)
{
cout << 1;
cout << 2;
}
Same thing goes for else statements
So this was for the brackets.
My wild guess for the post decrement is the following :
if you do m(n--), the value passed will be 5, the value of n will only change after the function call and go out of scope (so it won't matter). So what will happen is an infinite number of m(5) calls and that's why nothing is appearing. (I'm not sure about that part so please tell me if wrong) !
Hope it helped !
Looks like you confused with Python syntax, where scope of if is determined by indent. In C (and C++, C#, Java an many other languages) the scope is one statement (which ends with ;) unless you use curly brackets { and }. In the 1st variant of your code cout << n << ... will be always performed, regardless of value of n. In second variant it will be performed only if(n > 0)
I am trying to write two loops in one for loop so I looked up the syntax for multiple variables in the for loop
the problem is the second variable l isn't updating I don't know why
#include<iostream>
using namespace std;
int main ()
{
float vsum=0, lsum=0;
double nsum=0, msum=0;
float v=1, l=100000000;
for (v, l ; v<= 100000000, l >= 1 ; v++, l--)
{
vsum= vsum + 1/v;
nsum= nsum + 1/v;
lsum= lsum + 1/l;
msum= msum+ 1/l;
}
cout << " The float sum of all numbers 1 through 1/100000000 is " << vsum << endl;
cout << " The double sum of all numbers 1 through 1/100000000 is " << nsum << endl;
cout << "The float sum of all numbers 1/100000000 through 1/1 is " << lsum << endl;
cout << "The double sum of all numbers 1/100000000 through 1/1 is " << msum << endl;
cin >> vsum;
}
I guess your question is that after
float f = 100000000;
why does --f; leave f unchanged?
The answer is due to the granularity of float. The float does not have enough accuracy to store every possible integer. Clearly a 32-bit float cannot store as many integer values as a 32-bit int, for example.
The further away from 0 you get, the larger the gap gets between successive possible values of a float. On your system 100000000 - 1 is still larger than the next possible value of float below 100000000.
The rules of C++ are that when the result of the calculation is not representable exactly by a float, then it's implementation-defined whether the next-lowest value or the next-highest value is used. (So your compiler should actually document what happens here). In this case your system is using the next-highest value.
To get your intended results, make v and l be integral types, and do a float conversion in the actual calculation, e.g.
vsum += 1.f/v;
nsum += 1.0/v;
As dasblinkenlight mentions, you are only checking the second condition, but the second variable is updating just fine. Here is an abridged example that proves this.
#include<iostream>
using namespace std;
int main ()
{
float vsum=0, lsum=0;
double nsum=0, msum=0;
float v=1, l=10;
for (v, l ; v<= 10, l >= 1 ; v++, l--)
{
cout << v << " " << l << endl;
}
}
Output:
1 10
2 9
3 8
4 7
5 6
6 5
7 4
8 3
9 2
10 1