Java - Understanding Recursion - java

Can someone please explain to me why this prints out 1 2 3 4 5? I figured it would print out 4 3 2 1 0 but my book and eclipse both say I'm wrong.
public class whatever {
/**
* #param args
*/
public static void main(String[] args) {
xMethod(5);
}
public static void xMethod(int n){
if (n>0){
xMethod(n-1);
System.out.print(n + " ");
}
}
}

It is pretty simple, these are the calls
main
xMethod(5)
xMethod(4)
xMethod(3)
xMethod(2)
xMethod(1)
xMethod(0)
print 1
print 2
print 3
print 4
print 5
So you see the prints are 1,2,3,4,5

It's the result of the call stack. Here's what it would look like after a call with n = 5. Rotate your head about 180 degrees, since the bottom of this call chain is actually the top of the stack.
xMethod(5)
xMethod(4)
xMethod(3)
xMethod(2)
xMethod(1)
xMethod(0)
In a recursive call, you have two cases - a base case and a recursive case. The base case here is when n == 0, and no further recursion occurs.
Now, what happens when we start coming back from those calls? That is, what takes place after the recursive step? We start doing System.out.print(). Since there's a condition which prevents both recursion and printing when n == 0, we neither recurse nor print.
So, the reason that you get 1 2 3 4 5 as output is due to the way the calls are being popped from the stack.

It first call itself recursively and only when the recursive call finishes it prints.
So think about which call finishes first - it's when n = 0.
Then n = 1, etc.
It's a stack and you print after taking from the stack (after the recursion call), so the order is reversed.
If you printed before putting on the stack, then the order is preserved.

System.out.print(n + " ");
xMethod(n-1);
It will print 5 4 3 2 1. Because It will first print then call xMethod.
And in your case
xMethod(n-1);
System.out.print(n + " ");
Here it will reach to end condition then poped up and print. so 1 2 3 4 5

To explain how recursion works, let's see the sample of factorial calculation:
int factorial(int i) {
if (i == 0) {
return 1;
}
return i * factorial(i - 1);
}
For example let's get factorial value of 5:
int result = factorial(5);
Remember that exit value:
if (i == 0) {
return 1;
}
and return value:
i * factorial(i - 1)
Just look at iterations (according to return value):
5*factorial(4) -> 4*factorial(3) -> 3*factorial(2) -> 2*factorial(1) -> 1*factorial(0)
In fact it is:
5*(4*(3*(2*(1*factorial(0)))))
cause factorial(4) == 4*factorial(3), factorial(3) == 3*factorial(2), etc.
last iteration is factorial(0) that equals 1 (look at exit value).
In result:
5*(4*(3*(2*(1*1)))) = 120

xMethod is called until n is 0. The stack will then be xMethod(5)->xMethod(4)->xMethod(3)->xMethod(2)->xMethod(1)->xMethod(0). As it finishes xMethod(0), it will pop into the next line in xMethod(1), printing 1. This will then repeat until xMethod(5) is exited.
If you went and expanded each xMethod as it was called, the code would look something like this:
{
nA = 5 // What n was set at first
if (nA>0){
{
// Instead of xMethod(n-1),
// we're setting nB to nA - 1 and
// running through it again.
nB = nA - 1 // nB is 4
if (nB>0){
{
nC = nB - 1 // nC is 3
if (nC>0){
{
nD = nC - 1 // nD is 2
if (nD>0){
{
nE = nD - 1 // nE is 1
if (nE>0){
{
nF = nE - 1 // nF is 0.
if (nF>0){
// This will never execute b/c nF is 0.
}
}
System.out.print(nE + " "); // prints 1
}
}
System.out.print(nD + " "); // prints 2
}
}
System.out.print(nC + " "); // prints 3
}
}
System.out.print(nB + " "); //prints 4
}
}
System.out.print(nA + " "); //prints 5
}
}

1 public static void xMethod(int n){
2 if (n>0){ //the base condition
3 xMethod(n-1); //function is again called with one value less than previous
4 System.out.print(n + " "); //now print
5 }
6 }
Now look at line#3, As nothing is printed but the function is again called, so from line#3, the call reaches to line#1 again. which means, n was 5, but the new call takes n = 4 and it keeps going till line#2 tells that n is now less than 0.
When if condition fails at line#2, it reaches at line#5 and then line#6 which means the function has ended execution, and n = 1 at this time.
Now where should the call be returned? at line#3 where the last function was called and it will be popped out from stack executing line#4 which prints the value of n i.e. 1 2 3 4 5.

this
xMethod(n-1);
System.out.print(n + " ");
should be:
System.out.print(n + " ");
xMethod(n-1);

this is the right code
System.out.print(n + " ");
xMethod(n-1);

Related

why does the result of this recursive function in java is like that

1. static void h2(int n){
2. if(n<2)
3. h2(n+1);
4. System.out.print(n+" ");
5. if(n<2)
6. h2(n+1);
7. }
the function h2() is a recursive function
if I give n=0 the result of this function is : 2 1 2 0 2 1 2
can someone explain to me how does this function work ?
and what I wanna know also is next ==> for example in line 3 when the function h2(n+1); is called does the code continue to the next line and print the value on n or it goes and start over the function again ?
I added some print so I can see what happen :
1. static void h2(int n){
2. int i=0;
3. if(n<2){
4. System.out.println("i="+(++i)+" first n="+n+" ");
5. h2(n+1);
6. }
7. System.out.println("i="+(++i)+" n="+n);
8. if(n<2){
9. System.out.println("\ni="+(++i)+" second n="+n+" ");
10. h2(n+1);
11. }
12. }
and this is the output of this code :
i=1 first n=0
i=1 first n=1
i=1 n=2
i=2 n=1
i=3 second n=1
i=1 n=2
i=2 n=0
i=3 second n=0
i=1 first n=1
i=1 n=2
i=2 n=1
i=3 second n=1
i=1 n=2
Here is a test application to show you the trace of the program's execution (requires Java 11 due to the use of String#repeat(int)):
public class Main {
private static int depth;
public static void main(String[] args) {
foo(0);
}
public static void foo(int n) {
printDebug("Invoked foo(" + n + ")");
if (n < 2) {
printDebug("Recursively call foo(" + n + " + 1)");
depth++;
foo(n + 1);
depth--;
printDebug("Returned from recursive call of foo(" + n + " + 1)");
} else {
printDebug("Skip recursive call");
}
// this is the 'System.out.print(n + " "); line'
printDebug("PRINT VALUE OF n AND A SPACE (n=" + n + ")");
if (n < 2) {
printDebug("Recursively call foo(" + n + " + 1)");
depth++;
foo(n + 1);
depth--;
printDebug("Returned from recursive call of foo(" + n + " + 1)");
} else {
printDebug("Skip recursive call");
}
}
private static void printDebug(String msg) {
System.out.println(" ".repeat(depth) + msg);
}
}
The recursive function was renamed to foo and was slightly modified to accommodate debug statements. When you run the above, the output will be:
Invoked foo(0)
Recursively call foo(0 + 1)
Invoked foo(1)
Recursively call foo(1 + 1)
Invoked foo(2)
Skip recursive call
PRINT VALUE OF n AND A SPACE (n=2)
Skip recursive call
Returned from recursive call of foo(1 + 1)
PRINT VALUE OF n AND A SPACE (n=1)
Recursively call foo(1 + 1)
Invoked foo(2)
Skip recursive call
PRINT VALUE OF n AND A SPACE (n=2)
Skip recursive call
Returned from recursive call of foo(1 + 1)
Returned from recursive call of foo(0 + 1)
PRINT VALUE OF n AND A SPACE (n=0)
Recursively call foo(0 + 1)
Invoked foo(1)
Recursively call foo(1 + 1)
Invoked foo(2)
Skip recursive call
PRINT VALUE OF n AND A SPACE (n=2)
Skip recursive call
Returned from recursive call of foo(1 + 1)
PRINT VALUE OF n AND A SPACE (n=1)
Recursively call foo(1 + 1)
Invoked foo(2)
Skip recursive call
PRINT VALUE OF n AND A SPACE (n=2)
Skip recursive call
Returned from recursive call of foo(1 + 1)
Returned from recursive call of foo(0 + 1)
The indent of each line shows the current depth of the recursive calls (more indent means deeper recursion). If you look at the order of the PRINT VALUE OF n AND A SPACE (n=#) lines, you'll see the output of the original recursive function will be:
2 1 2 0 2 1 2

Java help - Output range with increment of 5

Write a program whose input is two integers, and whose output is the first integer and subsequent increments of 5 as long as the value is less than or equal to the second integer.
-15 10
the output is:
-15 -10 -5 0 5 10
Ex: If the second integer is less than the first as in:
20 5
the output is:
Second integer can't be less than the first. For coding simplicity,
output a space after every integer, including the last.
Here is the code I have gotten so far, however, it is producing an error at the bottom I have an example of the input, my output and what was expected. If anyone has any pointers or can show me updated code it would be appreciated.
import java.util.Scanner;
public class LabProgram {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int first = in.nextInt(), second = in.nextInt();
if (first > second) {
System.out.println("Second integer can't be less than the first.");
} else {
while (first <= second) {
System.out.print(first + " ");
first += 10;
}
System.out.println();
}
}
}
Here's what kind of error it is showing:
Input
-15 10
Your output
-15 -5 5
Expected output
-15 -10 -5 0 5 10
You can use the range function from IntStream:
IntStream.range(-15, 10).filter(x -> x % 5 == 0);
As suggested by MC Emperor, there also is a faster solution:
IntStream.iterate(-15, i -> i + 5).limit((10+15)/5);
/**
* The algorithm is as follows:
* iterate(start, i -> i + step).limit((stop-start)/step)
*/

Exercise java recursion

I don't understand how this exercise return the number's square. In particular I don't understand the sixth line in which there is return statement and after this "+2*x-1". What is the program behavior in that call?
public class Es {
public static int RecCalc(int x) {
if (x==0) {
return 0;
}else {
return RecCalc(x - 1) + 2 * x - 1;
}
}
public static void main(String[] args) {
System.out.println(RecCalc(3));
}
}
We can see how this works with a little algebra:
(x-1)² + 2x - 1
== x² - 2x + 1 + 2x - 1
== x²
If you are unfamiliar with the formula for (x + y)² then you can do (x-1)² by writing it as (x-1)*(x-1) and using the FOIL method or the distributive property. This is left as an exercise for the reader.
Let's step through, one call at a time.
The first call to kick it all off is:
RecCalc(3);
In Java, the return statement will take everything up to the semi-colon.
So, return 3 + 2 will return 5 to the caller.
RecCalc(3) will result in calling:
RecCalc(2) + 2*3 -1;
RecCalc(2) will result in calling:
RecCalc(1) + 2*2 -1;
RecCalc(1) will result in calling:
RecCalc(0) + 2*1 - 1;
RecCalc(0) will return 0.
Now we can work our way back up the call stack.
RecCalc(0) == 0
RecCalc(1) == RecCalc(0) + 2*1 -1 == (0) + 2*1 -1 == 1
RecCalc(2) == RecCalc(1) + 2*2 -1 == (1) + 2*2 -1 == 4
RecCalc(3) == RecCalc(2) + 2*3 -1 == (4) + 2*3 -1 == 9
This doesn't explain the math, but explains the recursion.
Let's look at the math.
As explained by #CodeApprentice, x² = (x-1)² + 2x -1
The real trick to this whole recursive scheme is the (x-1)².
We know that for x = 4, we can use (x-1)² plus some other junk to get the answer.
But that's just the square of 3 plus some other junk!
Now, to get the square of 3, we know that 3² = (x-1)² plus junk.
But that's just the square of 2 plus some other junk!
And so, we work our way down until we get to a trivial answer, where we return 0. (In fact, you could also return 1 for x=1).
I hope that explains it!
If you have 4 things, you can make a square with side 2:
xx
xx
If you want to make a square with side 3, you need 9 things: add 2 things on each of the side and bottom, plus 1 for the corner:
xx.
xx.
..+
Or, to put it another way, add 3 things on each of the side and bottom, take away 1 for the corner.
Generalizing, if you have a square of side length (n-1), to make a square of side length (n), you have to add on 2 lots of (n-1) things, plus one; or 2 lots of (n) things, take away one.
Hence:
number of things in a square of side length n
= (number of things in a square of side length (n-1))
+ 2 * (n-1) + 1
= (number of things in a square of side length (n-1))
+ 2 * n - 1
Perhaps if you put in a print statement it will help.
public static void main(String[] args) {
System.out.println(RecCalc(5));
}
public static int RecCalc(int x) {
if (x == 0) {
return 0;
} else {
int v = RecCalc(x - 1) + 2 * x - 1;
System.out.println((x-1) + " " + (2*x) + " " + (-1));
return v;
}
}
Prints
0 2 -1
1 4 -1
2 6 -1
3 8 -1
4 10 -1
25
Notice that the value of the sum of the last two columns in each line is an odd number. And the sum of any number of consecutive odd numbers starting with 1 is a perfect square. So essentially, this method just sums up the first x odd numbers.

"while" loop not iterating correctly

I am supposed to print the following output by using loops:
1
2 1
3 2 1
4 3 2 1
5 4 3 2 1
6 5 4 3 2 1
7 6 5 4 3 2 1
The highest number in this pattern (in this example, 7) is determined by user input. Here is the applicable code for the pattern:
index=patternLength+1; n=1; //These values are all previously intitialized
while (index!=1) {
index--;
printSpaces((index*2)-2); //A static method that prints a certain number of spaces
while(n!=1) {
n--;
System.out.print(n + " ");
}
System.out.print("\n");
n=patternLength+1-index;
}
And here is the incorrect output for the user input "7":
1
2 1
3 2 1
4 3 2 1
5 4 3 2 1
There are two blank lines preceding the incorrect output; these lines have the correct number of spaces necessary for the complete/correct pattern, but for some reason, the actual numbers start printing too "late" in the loop. In other words, the spaces that appear before the "1, 2 1" in the correct example are in the incorrect output. It's some of the numbers that are missing and make the incorrect example incorrect.
OK, I got it.
index=patternLength+1; n=1;int nSetter=1;
//Loop C
System.out.println("Pattern C:");
while (index!=1) {
index--;
printSpaces((index*2)-2);
while(n!=0) {
System.out.print(n + " ");
n--;
}
System.out.print("\n");
nSetter++;
n = nSetter;
}
My problem was that my "n" needed to go both up and down, so the extra variable "nSetter" seems to have solved that, although this may be a round-about solution. Whatever. Thanks to #Andreas for pointing me in the correct direction and #JohnKugelman for the helpful edit.
Please try this code your second while loop is not correct.
int index = patternLength + 1;
int n = 2; //These values are all previously intitialized
int i = 1;
while (index != 1) {
index--;
printSpaces((index * 2) - 2); //A static method that prints a certain number of spaces
while (n != 1) {
n--;
System.out.print(n + " ");
}
System.out.print("\n");
i++;
n = i+1;
}

Why does this while loop run after the condition is met?

When I do a regular while loop like this
int x = 0;
while (x < 2) {
System.out.println(x);
x = x + 1;
}
it prints
0
1
but this second while loop runs one more time after the condition is met.
class Hobbits {
String name;
public static void main(String [] args) {
Hobbits [] which = new Hobbits[3];
int number = -1;
while (number < 2) {
number = number + 1;
which[number] = new Hobbits();
which[number].name = "bilbo";
if (number == 1) {
which[number].name = "frodo";
}
if (number == 2) {
which[number].name = "sam";
}
System.out.print(which[number].name + " is a ");
System.out.println("good Hobbit name");
}
}
}
so the result is
bilbo is a good Hobbit name
frodo is a good Hobbit name
sam is a good Hobbit name
shouldn't it stop printing at "frodo is a good Hobbit name"
I set the condition for x < 2 so how does "sam" print if the while loop was supposed to stop at x == 1?
Edit: ohhh I get it now lol I was thinking like the increment was at the end of the code and the start was 0
Here's your test case more closely matching your code:
class Test {
public static void main(String[] args) {
int x = -1;
while (x < 2) {
x = x + 1;
System.out.println(x);
}
}
}
It does indeed print:
$ java Test
0
1
2
Your loop is not designed to stop when number is 2, it's designed to stop before the next iteration if the number is 2. Since you increment number early on in the loop, it will continue with that value until it's time to choose whether to iterate again.
Before the first iteration, number = -1 which is <2 so it should iterate.
Before the second iteration, number = 0, which is <2 so iterate.
Before the third iteration, number = 1, which is <2 so iterate.
Before the fourh iteration, number = 2, which is NOT <2 so stop.
You therefore get 3 iterations.
Your original test case had the right idea -- it's better to increment as the last step in the loop. That way, you start at 0 instead of -1, and you stop the loop based on the new value rather than the previous value.
I will try to trace through it for you.
First case this is what happens.
x = 0
is 0 < 2? yes
print 0
0 <- 0 + 1 // here it becomes 1
is 1 < 2? yes
print 1
1 <- 1 + 1 // here it becomes 2
is 2 < 2? no
exit program
second loop works a bit more like this
number = -1
is number < 2? yes
number <- -1 + 1 // here it becomes 0
make hobbit "bilbo" at index 0
0 does not equal either 1 or 2
print hobbit at index 0 who is "bilbo"
is 0 < 2? yes
0 <- 0 + 1 // here it becomes 1
number equals 1 so make "frodo" at index 1
print hobbit at index 1 who is "frodo"
is 1 < 2? yes
1 <- 1 + 1 // becomes 2
number equals 2 so make "sam" at index 2
print hobbit at index 2 who is "sam"
is 2 < 2? no
end program
There's nothing wrong in that behaviour. You set number = -1 and then you do a loop that will iterate while number < 2. So, -1, 0 and 1. Three iterations. What's the problem? Let's do a simple trace:
number = -1
(-1 < 2)? Yes. Execute code inside while.
number = number + 1 (0)
(0 < 2)? Yes. Execute code inside while.
number = number + 1 (1)
(1 < 2)? Yes. Execute code inside while.
number = number + 1 (2)
(2 < 2)? No. Continue with the next instruction after the while block.
you can solve this easily with replace
int number = -1;
to
int number = 0;
Because! -1 + 1 = 0;
Because you have 3 iterations that are true:
-1 < 2 == true
0 < 2 == true
1 < 2 == true
2 < 2 == false
Cheers

Categories

Resources