How does 1 2 3 come at the end? - java

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

Related

I Need an explanation about the next recursion (I'm a beginner)

I know that lowkey it does 1 + 2 + 3 + 4 = 10, but I want to know how exactly it does that
public class Main {
public static int sum(int n) {
if(n == 0) return 0;
return sum(n - 1) + n;
}
public static void main(String[] args) {
System.out.println(sum(4));
}//main
}//class
public static int sum(int n) {
if(n == 0) return 0;
return sum(n - 1) + n;
}
When you call sum(4), the compiler does the following steps:
sum(4) = sum(3) + 4, sum(3) then calls sum(int n) and go to next step
sum(3) = sum(2) + 3, sum(2) then calls sum(int n) and go to next step
sum(2) = sum(1) + 2, sum(1) then calls sum(int n) and go to next step
sum(1) = sum(0) + 1, sum(0) then calls sum(int n) and go to next step
sum(0) = 0, return the value and bring it to previous step.
Then with backtracking, the compiler brings the value of sum(0) to the formula sum(0) + 1, so the value of sum(1) is 1. And so on, finally we get sum(4) is 10.
The key to understanding how this recursion work is the ability to see what is happening at each recursive step. Consider a call sum(4):
return
sum(3) + 4
sum(2) + 3
sum(1) + 2
sum(0) + 1
return 0 in next recursive call
It should be clear how a sum of 10 is obtained for sum(4), and may generalize to any other input.
Okay so lets understand it :
you call the method from main method passing the argument as 4.
It goes to method , the very first thing it checks is called as base condition in recursion . Here base condition is if n == 0 return 0.
We skipped the base condition since n is not yet zero . we go to return sum(n-1)+n that is sum(4-1)+4 . So addition will not happen , because you made the recursive call again to sum method by decrementing the n value to n-1 , in this case it is 3.
You again entered the method with n =3, check the base condition which is not valid since 3 != 0 , so we go to return sum (n-1)+3 , which is sum(3-1)+3
Next recursive call where n = 2 , base condition is not valid 2!=0 , so we return sum(n-1)+2that is sum(2-1)+2.
Next call with n = 1 , base condition is not valid , we go to return sum(n-1)+1 that is sum(1-1)+1.
Next recursive call with n = 0 , so now base condition is met , means it is time to stop the recursion and keep going back to from where we came to get the desired result. So this time we returned 0.
Lets go back to step 6 , with 0 we got and compute the addition part of sum(1-1)+1 . You got sum(1-1) => sum(0) = . So sum(1-1)+1 will be equal to 0+1=1
One more step back with 1 as value to step 5 , where we have sum(2-1)+2 = sum(1)+2 , sum(1) you know , which is 1 , so we will return 1+2=3 from this recursive call.
One step back with value as 3 , to step 4 , sum(3-1)+3 = sum (2)+3 = 3+3 =6 .
Going one step back with 6 as value to step 3 , sum(4-1)+4 = sum(3)+4 = 6+4 = 10 . And that is where we started from . You got the result as 10.
Recursion itself is very easy to understand.
From a mathematical point of view, it is just a simple function call, such as your code:
public static int sum(int n) {
if(n == 0) return 0;
return sum(n - 1) + n;
}
/*
sum(0) = 0
sum(1) = 1
sum(n) = n + sum(n-1)
*/
In fact, the concept of recursion has been introduced in high school. It is the "mathematical construction method" that is often used to prove sequence problems. The characteristics are obvious: the structure is simple and the proof is crude. As long as you build the framework, you can prove it in conclusion. So what is a recursive "simple structure" framework?
Initial conditions: sum(0) = 0
Recursive expression: sum(n) = sum(n-1) + n
And in fact about the sum() function, every calculation starts from sum(0), and it is natural. Even if you are asked to calculate sum(1000), all you need is paper, pen, and time, so recursion itself is not difficult.
So why recursion give people an incomprehensible impression? That's because "recursive realization" is difficult to understand, especially using computer language to realize recursion. Because the realization is the reverse, not to let you push from the initial conditions, but to push back to the initial conditions, and the initial conditions become the exit conditions.
In order to be able to reverse the calculation, the computer must use the stack to store the data generated during the entire recursion process, so writing recursion will encounter stack overflow problems. In order to achieve recursion, the human brain has to simulate the entire recursive process. Unfortunately, the human brain has limited storage, and two-parameter three-layer recursion can basically make you overflow.
Therefore, the most direct way is to use paper to record the stacks in your head. It is very mechanically painful and takes patience, but problems can often be found in the process.
Or, go back to the definition of recursion itself.
First write the architecture and then fill it in. Define the exit conditions and define the expression.
Second implement the code strictly according to the architecture. Recursive code is generally simple enough, so it is not easy to make mistakes in implementation. Once there is a problem with the program result, the first should not be to check the code, but to check your own definition.
Meeting Infinite loop? The initial conditions are wrong or missing; wrong result? There is a problem with recursion. Find out the problem, and then change the code according to the new architecture. Don't implement it without clearly defining the problem.
Of course, it really doesn't work. There is only one last resort: paper and pen.

Recursion! I'm creating a method that counts back up and then down to a certain number, but I keep getting stuck in an infinite loop

So, I am currently creating a method for an assignment using recursion. I need to take an int, then print going down until it hits 0. After that, I need to print going up until it hits the original number, then stopping. Here's my code so far.
public static void recursivePrinter(int levels)
{
final int start = levels;
if (levels < start ) {
System.out.println("Going up! " + levels);
recursivePrinter(levels + 1);
}
else {
System.out.println("Going down! " + levels);
recursivePrinter(levels - 1);
}
return;
}
You don't reach the return; statement. the code always go in the else statement. to keep track of the starting number you could use a global variable . also you need to add a condition where the recursion should finish. so you can try some thing like this :
static int start = 10;
public static void recursivePrinter(int levels)
{
if (levels < start ) {
System.out.println("Going up! " + levels);
recursivePrinter(levels + 1);
}
else {
System.out.println("Going down! " + levels);
// recursivePrinter(levels - 1);
start-- ;
}
return;
}
In an attempt to provide a meaningful answer to help future visitors (as opposed to the comment thread on the question above)...
The initial problem was two-fold:
The method had no condition in which it doesn't recursively call itself. Which results in an infinite recursion. There must always be some condition by which the method stops recursion.
The method was locally storing a value that it doesn't need, and the logic was incorrectly assuming that value won't be different for each call to the method.
Essentially, a recursive method almost always follows a basic structure:
method(argument) {
terminating condition;
state change or method action;
recursive call;
}
Depending on the state change or the method action, this can be a bit more complex. But the basic components are generally always there in one form or another.
In your case, the argument is an integer, the terminating condition is testing whether that integer is a known value, the state change is changing the integer, the method action is printing the integer, and the recursive call is invoking the method with the new integer.
Based on your comment above:
It's supposed to count down from 3 (3, 2, 1) and then back up to 3 (1, 2, 3).
Consider the following pseudo-code (so as to not do your homework for you) structure:
myMethod(level) {
// terminating condition
if level is 0
return
// method action
print level
// recurse
myMethod(level - 1)
}
This would be a great time to step through the code in your debugger and see what a recursive method call actually does. Each time the method is invoked, it's an isolated action unaware of any other invocations of the method. It's "building a stack" of calls to itself. When the terminating condition is reached, that stack will "unwind" and those calls will all return to each other in reverse order.
Given this, printing the numbers "counting back up" is a natural result of just printing it again in the method:
myMethod(level) {
// terminating condition
if level is 0
return
// method action
print level
// recurse
myMethod(level - 1)
// more method action
print level
}
That last operation simply prints the value a second time. But it does so after the recursive call, therefore after all printing of lower numbers done within that recursive call, regardless of how many there are.

Java recursion outputs name forwards and backwards

I wrote a basic recursion problem in class a long time ago and I'm trying to remember how I'm getting the output that prints.
Its basically prints out a name forwards and backwards. I understand how it prints the name forwards but I'm clueless as to how it prints the name backwards. I did a debug to see step by step what is going on but can't understand how index is decreasing after the name prints forwards.
public class CharRecursion
{
public static void printName(String name, int index)
{
if(index > name.length() - 1)
{
return;
}
else
{
System.out.println(name.charAt(index));
printName(name, index + 1);
System.out.println(name.charAt(index));
}
}
public static void main(String[] args)
{
printName("Brian", 0);
}
}
The output is BriannairB
The backwards part comes from the second System.out.println(name.charAt(index)); statement.
This one is called only once the recursive call has ended, recursively, so you end up with the reverse String, look at the suffix markers :
System.out.println(name.charAt(index) + " - ");
printName(name, index + 1);
System.out.println(name.charAt(index) + " * ");
You get :
B -
r -
i -
a -
n -
n *
a *
i *
r *
B *
Since the actual sequence of calls is :
printName(name, 0) > printName(name, 1) > printName(name, 2) > printName(name, 3) > printName(name, 4)
The first call to resolve your second println statement will be printName(name, 4), then printName(name, 3), etc.. and the order of the printing becomes :
System.out.println(name.charAt(4) + " * ");
System.out.println(name.charAt(3) + " * ");
System.out.println(name.charAt(2) + " * ");
System.out.println(name.charAt(1) + " * ");
System.out.println(name.charAt(0) + " * ");
The way to understand this is to step through it manually, using pen and paper. I can't recommend strongly enough that you actually to this, physically, with real pieces of paper, until you understand what's going on.
Use one sheet of paper to record output.
Use a new separate sheet of paper for each invocation of printName().
Start at main(). When you see printName("Brian", 0), that's a signal to start a new sheet of paper. At the top of the sheet, write the inputs: name -
"Brian", index = 0.
Now you're in printName(), so go through it step by step. 0 is less than "Brian".length() - 1, so you can skip to the else block:
System.out.println(name.charAt(index)); - so write the result of "Brian".charAt(0) on your output sheet: B.
printName(name, index + 1) -- since you're seeingprintName()again, take another sheet of paper, write the inputsname="Brian", index = 1` at the top, and place this on top of the previous sheet.
Keep working in this way, and you will keep adding to your stack of paper. This is directly analogous to the execution stack that Java maintains; this is the same stack that you see in a stacktrace.
Eventually you'll reach a point where index = "Brian".length() -1, so you return. When you see return, remove the sheet you're working on, screw it up and throw it in the bin. The runtime has finished with this invocation of the method. Continue with the sheet underneath, where you left off. You are now at the second System.out.println(name.charAt(index));. So write that character on your output sheet.
When you finish, you will find you have written "BriannairB" on your output sheet, and you should have a better understanding of recursion.
Each piece of paper represents a stack frame. Bear in mind:
At a given moment during execution, only the topmost stack frame is "visible" as far as the execution is concerned.
Local variables and parameters are stored in the stack frame. At some moment in your execution, the value of index in the current stack frame will be 3. This has no effect on the value of index in the stack frame below -- that is a completely separate piece of storage, and will still be 2 when the 3 frame ends and is popped off the stack.
Once you get the hang of this, though, you can look at it at a more "declarative" level. What does printName("Brian",0) do?
It prints "B" then printName("Brian", 1) then "B".
I think this implementation is slightly easier to understand:
void printName(String s) {
if(s.length() > 0) {
System.out.println(s.charAt(0));
printName(s.substring(1));
System.out.println(s.charAt(0));
}
}
So, printName("Brian") writes B then printName("rian") then B.
Or going from the deepest the stack will go:
printName("") writes nothing.
Therefore printName("n") writes n then printName("") then n -- which is nn.
Following is the execution sequence of your program. Program calls printName("Brian",index) function recursively which executes first System.out.println(name.charAt(index)); before each call. When index reaches 5 function calls start returning and second System.out.println(name.charAt(index)); is executed after each return.

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).

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)

Categories

Resources