When I run this piece of code for n=5 the output I get is "5 3 1 1 3 5"
I get the 5 3 1 part but after that n=-1 but when I run the code with a debugger it when n=-1 it goes to the line after numbers(n-2);i.e System.out.prt(n+ ""); even though that statement is contained in the if block.
Why does this happen?
public void numbers(int n)
{
if(n>0)
{
System.out.print(n+" ");
numbers(n-2);
System.out.print(n+" ");
}
}
TLDR : when n=-1 System.out.prt(n+ "");even though it is within the if block which only runs when n>0.
Any help would be much appreciated. Thanks in advance!
Here is what happens behind the scenes, for n == 5:
numbers(5);
if(5 > 0)--> true :
System.out.print(5 + " "); // (1)
numbers(3);
| if(3 > 0)--> true :
| System.out.print(3 + " "); // (2)
| numbers(1);
| | if(1 > 0)--> true :
| | System.out.print(1 + " "); // (3)
| | numbers(-1);
| | System.out.print(1 + " "); // (4)
| System.out.print(3 + " "); // (5)
System.out.print(5 + " "); // (6)
Notice how each number is supposed to be printed twice:
System.out.print(n + " "); // print once
numbers(n-2);
System.out.print(n + " "); // print twice
Remove the final System.out.print(n+" ");
After the recursive numbers call it comes back with the original value for n and prints this again.
It bubbles back from the deepest level where it prints 1 two times up to the call with number 3, which is printed again, and also 5 is printed again.
If you want it to update the value after it is printed the first time you will have to update the variable n by performing n-=2 instead of n-2
5 first system.out then number(5-2)
|
----> 3 first system.out then number(5-2)
|
----->1 first system.out then number(5-2)
(smaller than 0) , returning
|
1 second system.out
|
3<---- second system.out
|
5<--------- second system.out
after n=-1, the recursive call will end and return back to the caller method to continue. first commands it found is print.
If you try to debug with the debugger, you will see how rational it is.
Java maintain method call into stack and as first 5,3,1 gets printed after which method call resume execution for remaining calls and prints 1,3,5 from stack(last call in stack get's picked up first).
Follow the recursion stack.
stack representation with and output flow:
------------------------->
5 3 1
num(5)--> num(3) --> num(1) --> num(-1) --> void
5 3 1
<-------------------------
Now since numbers(-1) does not satisfy the if condition, the program control comes out of the if block, and returns void.
Start popping out the stack now (recursion):
5 3 1 1 3 5. That's what the output you get, and is expected.
Related
I've been working on a program that lets you enter pizza toppings. It's pretty much complete, except for the removeToppings() method.
The problem is, I can't seem to figure out the correct way to remove the toppings in the index that the user chooses and all of the toppings BEFORE it. I have found numerous ways to remove indexes that come AFTER, but even then I can't find ways to reverse them.
Here's the method in question:
public static void removeTopping()
{
Scanner in = new Scanner(System.in);
printPizza();
System.out.println("What topping do you want to remove?\n"
+ "Keep in mind, this loses everything else above it.\n"
+ "Enter index number: ");
int remove = in.nextInt();
toppings.subList(remove, toppings.size()).clear(); //this is the problem line!
}
The printPizza() method would print something that looks like this:
|index|topping|
| 0 | cheese
| 1 | three
| 2 | cheese
| 3 | two
| 4 | cheese
| 5 | one
| 6 | sauce
| 7 | crust
Say I enter 5, the program would remove indexes 5, 6, and 7. I would want it to remove 0-5. Any pointers would be much appreciated.
You can use a for loop to achieve this.
The loop will start by removing the index specified by the remove variable. Then, the loop will decrement i until it reaches -1, by this point, it will have removed every element below the index you set.
for (int i = remove; i > -1; i--) {
myList.remove(i);
}
If in your example you also want to remove the position 5:
toppings.subList(0, remove + 1).clear();
In this program, if the user enters the number 3, the o/p will be 3 2 1 1 2 3 , I understood how 3 2 1 came, but I didn't understand how 1 2 3 came at the end.
class GFG{
static void printFun(int test)
{
if (test < 1)
return;
else
{
System.out.printf("%d ",test);
printFun(test-1); // statement 2
System.out.printf("%d ",test);
return;
}
}
public static void main(String[] args)
{
int test = 3;
printFun(test);
}
}
One way to trace through recursive functions is by expanding every recursive call, like a math expression.
First we start with
printFun(3)
That expands to:
print(3) // I have shortened System.out.printf here to just "print" to remove the noise
printFun(2)
print(3)
We still have a recursive call (printFun(2)), so let's expand that.
print(3)
print(2)
printFun(1)
print(2)
print(3)
Continue expanding:
print(3)
print(2)
print(1)
printFun(0)
print(1)
print(2)
print(3)
And one last time (since printFun(0) doesn't do anything, we just remove it):
print(3)
print(2)
print(1)
print(1)
print(2)
print(3)
Oh look! That will produce the output 3 2 1 1 2 3!
Ok - nature of recursions. Recursions put their calls on stacks which is built bottom-up. Whenever a member is recalled from the stack it is to be taken from the top till we reach the bottom again. Lets go through it line-per-line:
function is called 1st time with 3
function writes: 3 and calls itself with 2 - function halts (right after statement2) and waits for execution
function writes: 2 and calls itself with 1 - function halts and waits for execution
function writes: 1 and calls itself with 0 - call returns immediately because of value 0. Time to reduce the caller-stack and continue halted functions.
last function halt is reactivated (it was 1) and writes: 1 - then function returns
last function halt is reactivated (it was 2) and writes: 2 - then function returns
last function halt is reactivated (it was 3) and writes: 3 - then function returns
program stops.
Therefore you get the line of numbers you wrote.
The recursive invocation printFun(test-1) make the method goes on to invoke it in this way :
printFun(3); // original
printFun(2);
printFun(1);
printFun(0);
Arriving at this time it doesn't perform any other recursive call because of the condition encountered for printFun(0).
The current call that is the last recursive call (printFun(0)) goes on with return. Then the execution goes up to the caller of printFun(0) that is printFun(1) that executes the second System.out.printf("%d ",test); statement and it returns.
Then same logic : The execution goes up to the method that invoked that, that is printFun(2).
And that goes on to go up until the initial one invocation.
You can see calls in this way :
printFun(3)
printFun(2)
printFun(1)
printFun(0)
-- No more recursive call, execution goes on where we are
printFun(0)
printFun(1)
printFun(2)
printFun(3)
I added some print commands to help you understand this.
class GFG{
static int count = 1;
static String combined = "";
static void printFun(int test){
System.out.println("No of times Function printFun has been called : " + count);
count = count + 1;
if (test < 1)
return;
else{
System.out.println("Adding " + test + " to combined string");
combined = combined + test;
printFun(test-1); // statement 2
System.out.println("Returning to the previous call of printFun");
combined = combined + test;
System.out.println("Adding " + test + " to combined string");
return;
}
}
public static void main(String[] args){
int test = 3;
printFun(test);
System.out.println(combined);
}
}
I'm printing out the combined string at the end, the print statements should indicate how the function gets recursively called.
Function calls are maintained by stack. All local variables of the function corresponds to the function call instance. Each function call instance is maintained in Stack.
Statement above Recursive call is a PUSH operation and after recursive call is POP operation.
Hence its
(Statement before recursive call)
print(3) PUSH(3), print (2) PUSH(2), print(1) PUSH(1)
followed by
(Statement after recursive call).
POP(1) print(1), POP(2) print(2) , POP(3) print(3)
Hence output is 3 2 1 1 2 3
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)
I'm trying to understand how recursion works. I have two codes that have different outputs due to the placement of the recursive call. I understand that it's SUPPOSED to have different outputs, but I don't understand WHY the output is what it is.
Code 1 (recursive call placed AFTER print):
public class Test {
public static void main(String[] args) {
xMethod(5);
}
public static void xMethod(int n) {
if (n > 0) {
System.out.print(n + " ");
xMethod(n - 1);
}
}
}
The above output is 5 4 3 2 1. I understand why I get this output. It's because first, 5 is printed, then 5 is deducted by 1 and 4 is printed, and so on.
What is I don't understand is the output of the following code, when the recursive call is place before the print.
Code 2 (recursive call placed before print):
public class Test {
public static void main(String[] args) {
xMethod(5);
}
public static void xMethod(int n) {
if (n > 0) {
xMethod(n - 1);
System.out.print(n + " ");
}
}
}
The above output is 1 2 3 4 5. I can't figure out why I get this output. I would imagine the output to be 4 3 2 1, as the 5 is deducted, then printed as 4, and so on. But this obviously is not the case.
Can someone help me understand what is going on in the recursive process?
In first case printing is done and then call happens.
In second case calls happens in this way :
x(5) -> x(4) -> x(3) -> x(2) -> x(1) -> print(1) ->print(2) ->print(3) ->print(4) -> print(5)
Printing starts from the end call.
x(5)
|
x(4) print(5)
| |
x(3) print(4)
| |
x(2) print(3)
| |
x(1) print(2)
| |
print(1)
In case of first
print(5)
x(5)
|
print(4)
x(4)
|
print(3)
x(3)
|
print(2)
x(2)
|
print(1)
x(1)
In the first script,
public static void xMethod(int n) {
if (n > 0) {
System.out.print(n + " ");
xMethod(n - 1);
}
}
The output is printed before the step into the recursive call.
In the second script,
public static void xMethod(int n) {
if (n > 0) {
xMethod(n - 1);
System.out.print(n + " ");
}
}
The function keeps stepping "into" the recursion i.e. once xMethod(n-1) is called, the line below it is not executed i.e. the print statement. And this keeps happening until the last recursive call has been executed i.e. when x == 1, then the call goes backward and starts all the print statements beginning with the print statement for x == 1, then the print statement for x == 2 e.t.c. until the last print statement for the first call.
I have listed a stack trace of your second snippet's execution flow (Wish I could have aligned the table and 4 columns better)
If you step through your program when debugging it, you will obtain to a similar stack trace that tells you the value of the variables as you step through the program's execution flow, tabulated similar to the info listed below:
Stack trace| Value of Variable n | Statement executed | Output
main
xmethod(5) 5 xmethod(4)
xmethod(4) 4 xmethod(3)
xmethod(3) 3 xmethod(2)
xmethod(2) 2 xmethod(1)
xmethod(1) 1 xmethod(0)
xmethod(0) 0
xmethod(1) 1 System.out.print(1 + " ") 1
xmethod(2) 2 System.out.print(2 + " ") 1 2
xmethod(3) 3 System.out.print(3 + " ") 1 2 3
xmethod(4) 4 System.out.print(4 + " ") 1 2 3 4
xmethod(5) 5 System.out.print(5 + " ") 1 2 3 4 5
You should go through this tutorial(http://www.vogella.com/articles/EclipseDebugging/article.html) to get the hang of debugging. Debugging a program will help you to get a head-start to resolve queries like this one, yourself.
In the second code the line:
System.out.print(n + " "); will not be executed unless all the recursive calls get completed.
The recursive function is calling itself before executing the print line.
I made a function that computes the sum of digits of an integer. Trying to make the code shorter, I put in comment the if statement to see if it would still work so I can remove it but I get a StackOverflowError, why?
This is my code:
public static int sumDigits(int n) {
//if(n%10==n){ return n;}
return n%10+sumDigits(n/10);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println(sumDigits(12611));
}
It never returns, but just recurses deeper and deeper.
You do have a return statement, but before returning it needs to compute the value of the expression n%10+sumDigits(n/10) which involves infinite recursion.
NB: Each time you call the function from itself, the function's context (local variables) are added on top of the stack. The stack has a limited size. Eventually you reach that size and StackOverflowError is the error that's thrown in that condition.
That's because there is no stop clause. You will invoke sumDigits forever.
A recursive function can be defined as expressing an operation as a function of that operation on a value closer to an end point.
Hence, every recursive function needs an end condition at some point, otherwise it will recur infinitely (or, more correctly, until you blow your stack).
The basic definition of the "sum of digits" recursive method (for non-negative values of n) is:
def sumOfDigits (n):
if n < 10:
return n
return (n % 10) + sumOfDigits (n / 10) # assumes integer division.
That first bit, the end condition, is very important, and you seem to have commented yours out for some reason.
If you remove that line, your recursion does not have a base case any longer, which means it never returns.
stackover flow error occurs whenever the address stack in the memory allocated for the program can not store any new address.
so when you recursively call sumDigits() the system keep on saving the last tracked in LIFO manner. so that it becomes easy for the system to get back to the previously address, which is must for the recursion.
If you do recursion infinitely or above the memory constraints, you will suffer stackOverflow error.
The statement that you commented out was the base case for this recursive function. Without a base case this function will loop infinitely.
When you work out the example in the main method you get:
sumDigits(12611)
= 1 + sumDigits(1261)
= 1 + ( 1 + sumDigits(126))
= 1 + ( 1 + (6 + sumDigits(12)))
= 1 + ( 1 + (6 + ( 2 + sumDigits(1))))
= 1 + ( 1 + (6 + ( 2 + ( 1 + sumDigits(0))))) //at this point the commented out if statement would have returned
= 1 + ( 1 + (6 + ( 2 + ( 1 + ( 0 + sumDigits(0))))))
= 1 + ( 1 + (6 + ( 2 + ( 1 + ( 0 + ( 0 + sumDigits(0)))))))
...
At this point the program is stuck in an infinite loop. The commented out statement would have returned when n was 1, thus preventing this situation.
Because you are calling sumDigits() from itself and the code that should cause you to return from infinite recursion is commented out. Uncomment line if(n%10==n){ return n;}
Your recursion does not have a terminating condition. Else, you call the recursive function over and over again, eventually the stack will overflow
Uncomment your stop condition.