So in my class we are studying recursive functions. But I just do not understand how they work.
I'll use this code as an example.
// n is written to the screen vertically
// with each digit on a separate line.
void write_vertical(int n) {
if (n < 10)
{
cout << n << endl;
}
else // n is two or more digits long
{
write_vertical(n/10);
cout << (n % 10) << endl;
}
}
So if int n = 123; it will print each digit on its own line.How does this happen? how does this function work step by step?
Testing by random number (13)
Let's take 13 for an example. Well it's not less than 10, so it will execute the else block, and it will immediately execute the function itself with 13/10, which (as an integer) is 1. Now 1 is less than 10, so it will print 1 onto the screen with a new line because of endl. Now it will return back to the previous function call it had (before calling the function again with argument 1) and execute 13%10. 13 modulus 10 is 3, since its remainder becomes 3, with a new line (again because of endl). And voila, you printed the number in a vertical line!
For future
You should use a pencil and a paper, and debug it yourself manually just like we did above. OR even better use a debugger like GDB! This is an excellent quick startup on how to debug with GDB.
Recursion is simple. Assume you've already written your function; then use it.
Here it's the other way around - you are trying to figure out what the function does. Just the same, when you call it, it always does the same stuff.
So, in a general case of a number n > 10, what is n/10 (integer division)? It's that number without its last decimal digit.
What's n % 10? It's the number's last decimal digit.
So, your definition reads:
doing_something for a number `n` IS
doing_it for this number without its last decimal digit
(if there's something left, that is);
then printing its last decimal digit and a newline after it.
That's all.
1:
if(123 < 10) // fails
cout << 123; // skipped
else
{
recurse(123 / 10); // recurse(12) converted to int
cout << 123 % 10; // i'll be back here wait
}
2:
if(12 < 10) // fails
cout << 12; // skipped
else
{
recurse(12 / 10); // recurse(1)
cout << 12 % 10; // wiat I'll be back
}
3:
if(1 < 10) // succeeds! so now else executed
cout << 1; // printed
nothing is below until return of functions so we return
to 2:
cout << 12% 10; // (12 % 10 = 2) was wating it's its time
continue below: nothing below so return from function 2 to 1:
in 1:
cout << 123 % 10; // it was waiting so now it's its time
cout << 123 % 10; // 123 % 10 = 3
go below: nothing untile the end of function so retrun to main
where function was called first time (to the line after the call )
the result: 123
Related
I need to calculate the digits of a rational number that I get from the user.
The problem is that even though there is no errors in the code, the program running only part of the code. I'm working in Visual Studio.
int sumDigits(int a);
// main function
int main()
{
int ratioNum;
// Ask from the user to enter a rational number
cout << "Hello" << endl;
cout << "Please enter a rational number: ";
// Get the number from the user
cin >> ratioNum;
// Inform the user what is the sum of the digits
cout << "The sum of the digits are: " << sumDigits(ratioNum) << "." << endl;
return 0;
}
// Definition of function
int sumDigits(int a)
{
int digit = 0, sum = 0;
// As long as number is bigger than 0, continue
while (a > 0)
{
// Define a new verible - digit, as a number mudolo 10
digit = a % 10;
}
// kick out the units digit that we used
a / 10;
// Sum the digits of the number
sum = digit + a;
// Return sum to the main function
return sum;
}
You need a /= 10 instead of a / 10, and you need it inside the loop. Otherwise the loop will run forever because a never gets modified inside of it, so it can never become 0.
This will fix the infinite looping issue but the result will still not be correct. Why that is would be a different question though, and I'd invite you to learn proper debugging first (google how to debug C)! This will help you a lot more than copying a solution from here.
Your code isn't running the whole program because of these lines:
while (a > 0)
{
// Define a new verible - digit, as a number mudolo 10
digit = a % 10;
}
Inside the while loop, you're only assigning the value to the digit variable, but not changing the value of a, so the value of a always remains greater than 0. So your code gets stuck inside the while loop.
You should write
// kick out the units digit that we used
a /= 10;
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;
}
The problem's in the title.
If possible please give me exaplanations on what I did wrong and why correct solution is correct.
My attempt at solving it is in the code below... it was supposed get me all the 3 digit numbers then extract digit1, digit2 and digit3 from each number after which it should show the numbers that respect the digit3-digit1==digit2.
The program runs without errors but at the same time it doesn't really do anything.
#include <iostream>
using namespace std;
int main()
{
int Number,digit1,digit2,digit3,h;
for (Number=100; Number<=999; Number++)
{
h=Number;
}
digit1=h/100;
digit2=(h/10)%10;
digit3=h%10;
if (digit3-digit1==digit2)
cout<<digit1<<digit2<<digit3;
return 0;
}
The code that comes after the loop (other than return 0) has to go inside the loop. If it's outside the loop then it only works on the value 999, because that is the last value that h is set to before the loop exits. To print a new line you have to do cout << endl or just place << endl at the end of the print statement before the semicolon.
A few optimizations can be made here. You don't need to loop through all 899 numbers. Given the constraints the the third digit has to be greater than or equal to the first digit, so you can just run a loop for the first digit, and nested loop for the third digit that starts from the first digit.
for (int a = 1; a < 10; a++) {
for (int c = a; c < 10; c++) {
int b = c - a;
cout << a << b << c << endl;
}
}
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)
if (c % 3 == 0)
{
d=d+1;
}
else
{
cout << "The number has no digits divisible with 3" << endl;
}
But the thing is, c was used before in a while structure because I had to use it to calculate the sum of the number's digits and other things.
If I try to write this outside of the while, I believe c will get the value only of the first digit of the number because of the loop. I tried giving the value o c to another variable but it's still the same.
Maybe you should try putting your logic in another while loop, similar to the one you used before.
You can also try calculating the number of digits divisible by 3 in the same loop that you calculate the sum in
while(...)
{
...
sum = sum + c;
if(c%3 == 0)
{
d = d+1;
}
...
}