Trouble Understanding the Recursion Here - java

Can someone please help to explain to me why this ends up in an infinite recursion loop?
The variable length reaches the value 1 but for some reason the loop is still entered even though the loops condition is while (length>1).
I've tried printing values and running it over and over again, maybe I'm missing something more obvious or someone can explain this more simply. Thanks.
public static void main(String[] args) {
xMethod(5);
}
public static void xMethod(int length) {
while (length > 1) {
System.out.print((length - 1) + " ");
xMethod(length - 1);
}
}
Additional info.
When I dubugged this code :
public static void main(String[] args) {
xMethod(5);
}
public static void xMethod(int length) {
while (length > 1) {
System.out.print((length - 1) + " ");
xMethod(length - 1);
}
System.out.println("Coming out of while");
}
Below is the output :
4 3 2 1 Coming out of while
1 Coming out of while
1 Coming out of while
1 Coming out of while
1 Coming out of while
1 Coming out of while
1 Coming out of while
//repeated Infinite times
After coming out of while loop why it is going back in the same while loop with length as 2?
Edit: I appreciate all of your responses and understand that if I wanted to code something like this I would probably us an if statement as most recursive methods do but this is simply a question of me perhaps not understanding how the scope or call stack works. If I'm correct the while loop block holds on to the value of length as 2 no matter what happens outside of that block?

You are doing 2 things here. When you are writing a recursive code, you always need to think when the when code will end. Your code does not have a end case.
public static void main(String[] args) {
xMethod(5);
}
public static void xMethod(int length) {
System.out.println("Method Start "+ length);
while (length > 1) {
System.out.println("Inside while "+ length);
xMethod(length - 1);
}
System.out.println("Method End "+ length);
}
}
Now this code produces the following output:
Method Start 5
Inside while 5
Method Start 4
Inside while 4
Method Start 3
Inside while 3
Method Start 2
Inside while 2
Method Start 1
Method End 1
Inside while 2
Method Start 1
Method End 1
Inside while 2
Method Start 1
Method End 1
Inside while 2
Method Start 1
Method End 1
.
.
As you can clearly see,
Inside while 2
Method Start 1
Method End 1
is repeated again and again.
So what this means is, when the length is 2, the following will happen.
while (2 > 1) {
System.out.println("Inside while "+ length);
xMethod(1);
}
The output for this is
Inside while 2
Now, xMethod(1) doesn't even enter the while loop, so this will be printed.
Method Start 1
Method End 1
But you should now understand that while(2>1) is again execute because the length has not changed and it is still 2.
while (2 > 1){
System.out.println("Inside while "+ length);
xMethod(1);
}
goes on and the loop continues.

Because you are not updating the value of length in the current method. The value is just decremented when sending to the method.
public static void main(String[] args) {
xMethod(5);
}
public static void xMethod(int length) {
while (length > 1) {
System.out.print((length) + " ");
xMethod(length);
length--;
}
}

The variable length never reaches the value 1 in any loop, you mix two design and i think you need on of them, recursive method or loop.
first design:
public static void main(String[] args) {
xMethod(5);
}
public static void xMethod(int length) {
System.out.print((length - 1) + " ");
if(length > 1)
xMethod(length - 1);
}
}
another way:
public static void main(String[] args) {
xMethod(5);
}
public static void xMethod(int length) {
while (length > 1) {
System.out.print((length--) + " ");
}
}
you can select one of these, it depend on your design.
if it's not your answer, please write your expect output.

because when length reaches 2 xMethod(2) is called and therefore xMethod(1) follows, when xMethod(1) ends, since length is still 2 it again calls xMethod(2) and the this calls xMethod(1) it repeates..
to fix it, use return after xMethod(length - 1);
public static void main(String[] args){
xMethod(5);
}
public static void xMethod(int length) {
while (length > 1) {
System.out.print((length - 1) + " ");
xMethod(length - 1);
return;
}
System.out.println("Coming out of while");
}

Related

Divisible by three

i'm new in coding and tried to do some open university tasks. Maybe you guys can give some helping hand. I really even don't know how to start this task, witch is divide three Integers from main to method. Example 2, 10 where I should print 3, 6, 9 or 2, 6 where I should print 3, 6.
import java.util.Scanner;
public class divideByThree {
public static void main(String[] args) {
Scanner reader = new Scanner(System.in);
divideByThree(2, 10);
}
public static void divideByThree(int start, int end) {
while(true) {
if (start % 3 == 0) {
start++;
}
if (end % 3 == 0) {
System.out.println(end);
}
System.out.println(start);
}
}
}
How about the following implementation about divideByThree method?
public static void divideByThree(int start, int end) {
for(int i = start; i <= end; ++i){
if(i%3==0){
System.out.print(i+" ");
}
}
}
Do not use while(true) because it creates an infinite loop which will unnecessarily make your program complex.
You need to increase start by 1 in each iteration and terminate the loop when the value of start value goes beyond end.
Whenever start % 3 == 0 becomes true, print start.
Given below is a sample code which you can use to understand the points mentioned above.
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner reader = new Scanner(System.in);
System.out.print("Enter the start number: ");
int start = reader.nextInt();
System.out.print("Enter the end number: ");
int end = reader.nextInt();
divideByThree(start, end);
}
public static void divideByThree(int start, int end) {
while (start <= end) {
if (start % 3 == 0) {
System.out.println(start);
}
start++;
}
}
}
A sample run:
Enter the start number: 3
Enter the end number: 9
3
6
9
Recursive Approach
import java.util.Scanner;
public class DivideByThree {
public static void main(String[] args) {
Scanner reader = new Scanner(System.in);
int start = reader.nextInt();
int end = reader.nextInt();
divideByThree(start, end);
reader.close();
}
public static void divideByThree(int start, int end) {
if(start % 3 == 0) {
System.out.println(start);
}
if( start <= end) {
divideByThree(++start, end);
}
}
}
The while(true) is an endless loop (something you would want to avoid). It will only stop if you add a break statement somewhere inside it, which you do not have.
I assume this is the issue you need to solve. The key to solving it is simply making sure that your loop stops at some point. How do you do that?
True is a boolean value. a while loop runs again and again for as long as the specified condition remains true, and in your case - it is always true. What you need to do is replace while(true) with while(some condition that will be false at some point). In your specific case, while(start <= end) seems appropriate - just make sure to increment start at every iteration.
Another way of doing it would be using a for loop, i.e:
for (int i = start; i <= end; i++) {
// your code
}
This type of loop takes care of stating the conditions for which the loop should keep on running, and also takes care of incrementing the index i to make sure the loop stops running at some point.
I will make some small changes in your code only so that you will be able to understand quickly.
public static void divideByThree(int start, int end) {
while(start! =end) {
if (start % 3 == 0) {
System.out.println(start);
start++;
}
}
}

Why does this while loop never terminate?

I am really stuck on understanding this one concept. I had a while loop from one of my exams, and even though I know what prints, I don't know why.
Here is the code:
class Test {
public static void xMethod(int length) {
while (length > 1){
System.out.print((length - 1) + " ");
xMethod(length-1);
}
}
public static void main(String[] args){
xMethod(5);
}
}
Because length is never updated.
while (length > 1){
System.out.print((length - 1) + " ");
xMethod(length - 1);
length--;
}
As the other answer have point it out, you need to decrements the length variable to fix your current problem with length = length - 1 or length--. (I let my "colleague" answer to explain it better).
My answer is mostly about you usage of a recursive method.
What you probably want is simple an if condition. The recursion will act as loop.
public static void xMethod(int length) {
length--;
System.out.print((length) + " ");
if (length > 1){
xMethod(length);
}
}
xMethod(5) > 4 3 2 1
public static void xMethod(int length) {
length--;
if (length > 1){
xMethod(length);
}
System.out.print((length) + " ");
}
xMethod(5) > 1 2 3 4
Length is not changing at all
class Test {
public static void xMethod(int length) {
while (length > 1){
System.out.print((length - 1) + " ");
xMethod(length-1);
//need to change the length here
}
}
public static void main(String[] args){
xMethod(5);
}
The important thing to add here is to understand how the assignments work in Java.
The value of length is not changed because when you pass a value in the method and it goes in the while loop, the loop stops when the condition stops but not the recursion xMethod(length-1); you have used. That's why even if you add length-- it will not print what you desire.
So for the program to work properly, you have to
Assign value to length variable
Change or remove the recursion.
https://docs.oracle.com/javase/tutorial/java/nutsandbolts/op1.html
And once you go through the link, you will understand the why the value is not changing.
Note: From the link you come to know that length-- is equal to length = length -1, so basically we have to assign the updated value to length variable.
length is always have the value 5. you should replace length-1 by length--.
class Test {
public static void xMethod(int length) {
while (length > 1){
System.out.print((length--) + " ");
xMethod(length);
}
}
public static void main(String[] args){
xMethod(5);
}
}

Recursive Counting By Integers Up and Down

I received this assignment today and I am kinda stuck on it.
This is what the assignments say:
Write a method called recursiveUpAndDown() that takes one non-negative integer parameter, recursively starts at zero and prints all the integers from zero to the parameter (that is, prints 0, 1, 2, etc. all the way up to the parameter), then recursively starts at the integer parameter and prints all the integers from the parameter to zero (that is, prints the parameter, the parameter - 1, the parameter - 2, etc. all the way down to 0).
I was able to write the code for writing the coding to count down then up but unable to do up then down. Here is the code I wrote
class myCounter{
static void recursiveDownAndUp(int i)
{
if (i < 1)
return;
else
{
System.out.printf("%d ",i);
recursiveDownAndUp(i-1); // recursive call
System.out.printf("%d ",i);
return;
}
}
public static void main(String[] args)
{
recursiveDownAndUp(10);
}
}
We are not allowed to use 2 parameters, a helper method or a global variable. I know it seems hard, at least for me, but the professor said it is doable
static String recursiveUpAndDown(int n) {
if (n < 0) return "";
String x = recursiveUpAndDown(n - 1);
System.out.print(n + " ");
return n + " " + x;
}
public static void main(String[] args)
{
System.out.print(recursiveUpAndDown(10));
}

What is the output of following code

It should print only Number: -1
but it is printing Number: -1 0 1 2
Why it is printing this series?
I expect execution will go only once to System.out.println.
class MemoryJava {
public static void main(String[] args){
decreaseNumberbyOne(2);
}
public static void decreaseNumberbyOne(int num){
if(num >= 0){
decreaseNumberbyOne(num -1);
}
System.out.println("Number:"+num);
}
}
This is the sequence of events:
call (2)
call (1)
call (0)
call (-1)
do not call (-2) because <0
print -1
return
print 0
return
print 1
return
print 2
return
It is called recursion.
I would show code with an else to help you achieve the desired output, but for that look at the other answer by deadpool.
Try this will work, just mistake in your code, add System.out.println("Number:"+num); in else block
public static void main(String[] args){
decreaseNumberbyOne(2);
}
public static void decreaseNumberbyOne(int num){
if(num >= 0){
decreaseNumberbyOne(num -1);
} else{
System.out.println("Number:"+num);
}
}

Printing text with spacing recursively

This is an assignment for school. I am having trouble understanding how I can print the following recursively:
This was written by call number 2.
This was written by call number 3.
This was written by call number 4.
This ALSO written by call number 4.
This ALSO written by call number 3.
This ALSO written by call number 2.
This ALSO written by call number 1.
I'm not sure if I am supposed to be illustrating a loop vs. recursion or if there is a way to print all of this recursively. Additionally, how would I go about reversing the recursion call so it starts from 4 as per the example output?
This is my current output.
This was written by call number 2.
This was written by call number 3.
This was written by call number 4.
This ALSO written by call number 1.
This ALSO written by call number 2.
This ALSO written by call number 3.
This ALSO written by call number 4.
There is no spacing implemented in the for loop yet b/c I'm not sure if that part is also supposed to be recursive.
My code:
public class Recursion {
public static void main(String[] args) {
for (int i = 2; i < 5; i++) {
System.out.println("This was written by call number " + i + ".");
}
recurse(4);
}
public static void recurse(int n) {
String temp = "";
for (int i = 0; i < n; i++) {
temp += " ";
}
if (n < 2) {
System.out.println("This ALSO written by call number " + n + ".");
}
else {
recurse(n - 1);
System.out.println(temp + "This ALSO written by call number " + n + ".");
}
}
A simpler solution.
public static void main(String[] args) {
recurse(1);
}
public static void recurse (int n) {
if (n==5) return;
String temp="";
for (int i=0;i<n;i++) temp += " ";
if (n!=1) {
System.out.println(temp + "This was written by call number " + n + ".");
}
recurse(n+1);
temp=" ";
for (int i=0;i<n;i++) temp += " ";
System.out.println(temp + "This ALSO was written by call number " + n + ".");
}
The key to writing most recursive programs (especially the ones you're given as assignments) is to look for a larger problem that contains a similar but smaller occurrence of the same problem.
In your case, the "larger problem" would be to print the 6 lines that start and end with "call number 2". That is, print lines for call numbers 2 through 4. The way to do this is: print the first line that says "call number 2", solve the problem to print the 4 lines for call numbers 3 through 4, and print the last line that says "call number 2". The part in the middle is the smaller occurrence of the same problem. That's going to be the recursive call.
Since your larger problem is going to start with "call number 2", and your smaller problem is going to start with the call number that's one higher, I'd recommend arranging things so that you call recurse(n+1) instead of recurse(n-1). If you do that, you'll need a second parameter so that you know when to stop recursing--something like recurse(n+1, last).
Hopefully this will be enough to get you thinking on the right track.
Try this:
public static void main(String[] args) {
recurse(1, true, 1);
}
public static void recurse(int n, boolean loop, int add) {
String temp = "";
String out = "";
for (int i = 0; i < n; i++) {
temp += " ";
}
if (add > 0) {
out = temp + "This was written by call number ";
} else {
out = temp + "This ALSO written by call number ";
}
if (n == 1 && !loop) {
System.out.println(out + n + ".");
return;
} else if (n == 1) {
recurse(n+add, false, add);
} else if (n == 5) {
add = add - 2 * add;
recurse(n+add, false, add);
} else {
System.out.println(out + n + ".");
recurse(n+add, false, add);
}
}
Here is quite a straightforward solution. Also pay attention how you can easily get the indent string (via substring). The recursion is as simple as it gets: print the number, enter the function with a larger number if below the max, then follow back.
class R{
static final String spaces=" ";
public static void main(String[] args) {
rec3(1,4);
}
private static void rec3(int i, int max) {
if (i>1) System.out.printf("%sThis was written by call number: %d%n", spaces.substring(0, i-1), i);
if (i<max) rec3(i+1, max);
System.out.printf("%sThis was ALSO written by call number: %d%n", spaces.substring(0, i-1), i);
}
}
Thanks to everyone for the help. I ended up modifying the solution from #JoseLuis a little bit.
public class Recursion {
public static void main(String[] args) {
recurse(1, 5);
}
public static void recurse(int n, int max) {
String temp = "";
for (int i = 0; i < n; i++) {
temp += " ";
}
if (n == max) {
return;
}
if (n != 1) {
System.out.println(temp + "This was written by call number " + n + ".");
}
recurse(n + 1, max);
System.out.println(temp + "This ALSO was written by call number " + n + ".");
}
}

Categories