Recursive call has finish in a function but continue printing integers - java

I tried to investigate what will happen if I write some code after the recursive call and here is the code. I tried to trace the code but I didn't get what was going on. I thought the function will be terminated once my program prints the last value for x since the value for x doesn't satisfy the if loop condition. I executed this code, the result wasn't understandable. Any help would be appreciated.
public class Recursive {
public static void main(String []args){
int a=5;
call(a);
}
public static void call(int x) {
System.out.print(x+"\n");
if(x>0) {
x--;
call(x);
}
System.out.print(x);
}
}
Expected output:5 4 3 2 1 0 0
My output: 5 4 3 2 1 0 0 0 1 2 3 4

instead of while, you can try If condition and remove the last print.
public static void call(int x) {
System.out.print(x+"\n");
if (x>0) {
x--;
call(x--);
}
}

You forgot to say what was surprising or confusing, which indicates that you don't understand the problem (hence two downvotes). Here is what I think may be confusing. The decrement operator x-- first returns the value of a variable and then lowers it's value. So if you run
z= 25
dothedoo(z--)
the value inside dothedoo will be 25, not 24. The alternative --x will lower the value first and then return the value.

This is your code.
public static void call(int x) {
System.out.print(x + "\n");
while (x > 0) {
x--;
call(x);
}
}
Lets consider this call stack with an input of x=2
1) call(2)
2) print x // 2
2) x-- (becomes 1)
3) recursive call to call(1) // remember the call(2) is suspended right now.
4) print x //1
5) x -- (becomes 0)
6) recursive call to call(0)// remember the call(2) and call(1) is suspended right now.
7) print x //0
8) x-- (becomes -1)
9) recursive call to call(-1) // breaks the loop since it doesnt match the condition, resumes flow to the suspended call(1) function.
10) refer step 5 for the value of x.
11) breaks the loop for the call(1) function. // resumes call(2) which was suspended.
12) refer step 2 where x is still 1.
13) moves on with another call(1)
14) this results in printing an extra 0; from the call in step 13
Your while loop is messing up the program.
Your variable in the recursion is passed by value, hence your actual
value of x which is caller's value isnt decremented globally in the caller when you do this call(x) the x which is used after
decrementing in your recursive call is a copy of the x that you have
decremented in the caller.
Please refer to this article to understand more on it.
Also, the while loop is notorious here based on the explaination provided in this answer and what you actuall need is an if loop

Related

Reversing recursive java methods

I am reading a book called "Think Java: How to think like a Computer Scientist", and I recently covered recursive methods.
public static void countdown(int n)
{
if (n == 0) {
System.out.println("Blastoff!");
} else {
System.out.println(n);
countdown(n - 1);
}
}
This would be a normal recursive method used to count down to 0 and I understand what is happening, but if you make the recursive call before the System.out.println like this
public static void countdown(int n)
{
if (n == 0) {
System.out.println("Blastoff!");
} else {
countdown(n - 1);
System.out.println(n);
}
}
it counts the opposite way, so If I gave the argument 3 for both of these conditional statements the 1st one goes "3, 2, 1, Blastoff!" but the 2nd 1 goes "Blastoff, 1 ,2 ,3".... I don't understand how this works, can someone try to explain what is happening in this code that makes it count in the opposite way?
I'll try to visualize it for you.
First method
countdown(3) (first call)
"3" (sysout)
countdown(3-1) (second call)
"2" (sysout)
countdown(2-1) (third call)
"1" (sysout)
countdown(1-1) (fourth call)
"Blastoff!" (n == 0)
Second method
countdown(3) (first call)
countdown(3-1) (second call)
countdown(2-1) (third call)
countdown(1-1) (fourth call)
"Blastoff!" (n == 0. going back up call stack)
"1" (sysout)
"2" (sysout)
"3" (sysout)
Think of it this way... In the first case you will always print before going down the next function, so...
countdown(3)
System.out.println(3)
countdown(2)
System.out.println(2)
countdown(1)
System.out.println(1)
countdown(0)
System.out.println("Blastoff")
Result: 3 2 1 Blastoff
In the second case, because you print it first, your run will go all the way down the recursion until the base case to start printing...
countdown(3)
countdown(2)
countdown(1)
countdown(0)
System.out.println("Blastoff")
System.out.println(1)
System.out.println(2)
System.out.println(1)
Result: 1 2 3 Blastoff
Recursion is tough! I hope I helped :)
It doesn't count "the opposite way", it's just that it "unravels" in an order you are perhaps not expecting. Try writing out what you expect to happen and I'll be happy to help resolve the misconception.
The issue is that the print line is going to wait until your function call(s) have finished. Therefore it will call the function 3 times in a row before it gets to the first print line
The whole point of recursion is that every step gets its own "stack frame" with its own local variables, that it remembers.
So even if you change n inside of one iteration, the function that called this iteration will still retain its own value of n. When the time comes to print this n it will still be the original value (one bigger than the one in the following iteration).

javaBegginer - how to counts from 10 to 0 using while/do while

I started learning Java and I can't solve this:
I want to code program which will be counting from 10 to 0 using "do while" and show numbers from 9 to 1.
I did this:
public class exWhile {
public static void main(String[] args) {
int a = 10;
do {
--a;
System.out.println(a);
} while (a==1);
}
}
Why this wont working?
The loop exits almost immediately after the first iteration since the exit condition has been met. Use
...
} while (a != 1);
Your loop is saying "while a equals 1" do stuff. Since a isn't initialized to 1, it's only going through the do-while loop once.
What you want to do is
while(a != 0)
or you can also do
while (a > 0)
to print 10 thru 0.
What your code is saying is to continue looping through prints while the value of a is one. You stay a at ten, so this is not true, and the loop exits.
You want to do something like this
While(a!=0){
System.out.println(a);
a--}

What causes this recursive function to crash compared to another nearly identical one? [duplicate]

This question already has answers here:
How do the post increment (i++) and pre increment (++i) operators work in Java?
(14 answers)
Closed 7 years ago.
This causes a Stack Overflow error. I just need help explaining why this one crashes compared to the correct one which is similar. I have used the debugger, but it is still unclear to me.
public static void main(String[] args) {
countForwards(5);
}
public static void countForwards( int num ) {
if (num >= 0){
countForwards(num--);
}
System.out.print(num + " ");
}
I know this is the solution but I don't understand why it is different
public static void countForwards( int num ) {
if (num >= 0){
countForwards(num - 1);
}
System.out.print(num + " ");
}
countForwards(num--) passes the original value of num to the recursive call, which means the recursion never ends.
countForwards(--num) would allow the recursion to end.
After seeing all the traffic this question got, I thought it would be worth it to expand the answer a little.
As paxdiablo commented, even though countForwards(--num) allows the recursion to terminate, it behaves differently than countForwards(num-1).
Both variants would cause the following series of recursive calls :
countForwards(5)
countForwards(4)
countForwards(3)
countForwards(2)
countForwards(1)
countForwards(0)
countForwards(-1)
but they will output a different series of numbers when the recursion unwinds :
num - 1
-- num
-1
-1
0
-1
1
0
2
1
3
2
4
3
5
4
The reason for the difference is that num-1 doesn't change the value of num while --num decrements num.
num-- uses a postfix operator -- which means that original value i.e. num is passed and its value is decremented after it is passed.
The interesting thing about a postfix operator i.e. the one we are using in this example is that operation is performed and then the value is incremented or decremented. Please refer to official documentation about operators in java
class PrePostDemo {
public static void main(String[] args){
int i = 3;
i++;
// prints 4
System.out.println(i);
++i;
// prints 5
System.out.println(i);
// prints 6
System.out.println(++i);
// prints 6
System.out.println(i++);
// prints 7
System.out.println(i);
}
}
Post-Decrement
Post-Decrement takes the form variable-name operator. This tells the compiler to first use the original value and afterawrds decrement it, so if we have something like this:
for (int i = 10; i > 0; i--)
{
System.out.println(i);
}
The output will be as follows
1: 10
2: 9
3: 8
4: 7
5: 6
6: 5
7: 4
8: 3
9: 2
10: 1
Pre-Decrement
Pre-Decrement takes the form operator variable-name and is used when you want to decrement before you use the value. The same code above would terminate at 0 instead of 1. This is because the function decremented the value before it used the value.
How does this apply to recursive calls?
Each recursive call is it's own stack, so when you pass num-- to the recursive function, you're literally passing the original value of num, and when the child call terminates (in this case never) the parent call will then decrement num. Since you don't have another base case which correctly terminates the call, it results in infinite recursion.
Actually it is happening due to post decrement operator in the method.
public static void countForwards( int num ) {
if (num >= 0){
countForwards(num--);
}
System.out.print(num + " ");
}
Now when the function is calling the countForwards again it is always taking value of num as 5 due to post decrement in the method, please try to change as pre-decrement
public static void countForwards( int num ) {
if (num >= 0){
countForwards(--num);
}
System.out.print(num + " ");
}
This will be work because value is first decremented and then that value is using method.
as function is calling again and these are primitive and stores in the stack. Thats why it is showing stack overflow.
public static void countForwards( int num ) {
if (num >= 0){
countForwards(num - 1);
}
System.out.print(num + " ");
}
This is working because this is an expression which try to solve first itself and then the function can use the value of that expression. I hope it will answer your question.

In the following function why After showing Hello(6,5,....1),then space shows increment in counter?

In the following function why After showing Hello(6,5,....1),then space shows increment in counter?
private void myMethod(int counter)
{
if (counter == 0)
{
System.out.println("");
}
else
{
System.out.println("Hello" + counter);
myMethod(--counter);
System.out.println("" + counter);
}
}
Program Output when 6 is passed to method:
Hello6
Hello5
Hello4
Hello3
Hello2
Hello1
0
1
2
3
4
5
The second print is first called if the recursion is fully done, this means it counts backwards, since the last called method finishes first.
If that's what you mean.
(not actually code but used for a diagram)
When using myMethod(3):
mM(3)->|prints: "Hello3"
|mM(2)-------------->|prints: "Hello2"
|prints:.... |mM(1)-------------->|prints: "Hello1"
|prints.... |mM(0)----------->|prints: ""
|prints....
because each else has three statements, and they do them in order from top to bottom, the first print statement is executed first, and then the recursion happens next, which temporarily skips the the second print until the base statement 0 is reached, and then it goes backwards and does the second print for each else. (if this is what you're asking)

Number pyramid,beginner recursion tracking difficulty?

I am a beginner in JAVA, and I am having some difficulties tracking recursion and understaning it fully and so here I have the code for a program that if we write 3, it will output:
1
12
123
12
1
Or if we write 5, it will output
1
12
123
1234
12345
1234
123
12
1
public class Aufgabe3 {
private static void printSequenz(int n) {
if(n<1) {
return;
}
printLoToHi(n-1);
printMany(n);
printHiToLo(n-1);
}
private static void printHiToLo(int n){
if(n<1){
return;
}
printMany(n);
printHiToLo(n-1);
}
private static void printLoToHi(int n){
if(n<1){
return;
}
printLoToHi(n-1);
printMany(n);
}
private static void printMany(int n){
for(int i=1;i<=n;i++){
System.out.print(i);
}
System.out.println();
}
public static void main(String[] args) {
printSequenz(5);
}
}
Now here is what I don't understand. For example at the method printHiToLo it calls the method printMany(n), and then it calls itself for n-1, and this repeats until n is greater than 0. But I don't understand how the method printLoToHi works? How does it ever reach the printMany method? If it just calls itself until n is greater than 0. This is really confusing to me... Thanks to anyone that helps me out :)
private static void printLoToHi(int n){
if(n<1){ // This is the base case that terminates the recursion.
return; // You'll always have one - sometimes more.
}
printLoToHi(n-1); // This is where the recursion takes place.
printMany(n); // But when n < 1 it returns to here and continues on.
}
So you see it does indeed get called; only after the base case (n < 1) is reached.
An easy example would be if you called it with printLoToHi(1)...
It will pass the if condition.
It calls itself with n - 1 (0) as an argument.
This time it fails the condition and returns.
n == 1 in our original method.
printMany(1) is called.
Look, your functions are executed line by line. So in printLoToHi recursive call is executed and then printMany is called.
For example how works printLoToHi(3):
It checks if 3 less than 1. Then calls printLoToHi(2).
It checks if 2 is less than 1. Then calls printLoToHi(1).
It checks if 1 is less than 1. Then calls printLoToHi(0).
It checks if 0 is less than 1. It is, so it returns.
Then printMany(1) is called.
Then printMany(2) is called.
Then printMany(3) is called.
You can consider a recursive call as a single function which does something and don't think how it works. You can assume it works and write other part of function. If that part is correct - the recursion is correct.

Categories

Resources