Why does the following recursive program give the following output - java

I am trying to understand the java recursion from beginning. I came through a following example
public static void main(String[] args) {
threeWays(1,4);
}
public static void threeWays(int id,int n) {
if (n >= 0) {
System.out.println(id + "=" + n);
threeWays(id+1,n-1);
threeWays(id+1,n-2);
}
}
gives the output
1=4
2=3
3=2
4=1
5=0
4=0
3=1
4=0
2=2
3=1
4=0
3=0
I understand up to 5=0 but why does the program run beyond that? Why doesn't it stop once n becomes -1? Where does 4=0 come from? I don't even know what to call this phenomenon so the question might look vague. Any help would be appreciated.

threeWays(id+1,n-1); // when this returns,
threeWays(id+1,n-2); // ... the program still does this
You are recursively calling the function twice. So after it reaches the end for the first call, it unwinds the stack a little and then goes into the second recursion.
And from that second call, it branches out twice again at each layer.
If this is confusing, it could be illustrative to step through the program in a debugger. You can see each frame in the call stack there, including the local variables and which line of code they are in right now.

Related

How to unreverse this method in java?

I wrote some code:
public class digitShow {
public static void main(String[] args) {
System.out.println(digitShow(98198187));
}
public static int digitShow(int num) {
if (num != 0) {
System.out.print(num % 10);
return digitShow(num / 10);
} else
return num;
}
}
The code works perfectly fine, but I am trying to make it so instead of printing the numbers in reverse order one by one, the output rather would display each digit one by one in the order that they are entered in the parameter.
So in this case:
1
2
3
4
I've been trying to un-reverse it, but I've had no luck.
Ok, some people on comments are suggesting using arrays or similar. This is correct, however this seems like a question made by someone who is learning recursion (and, as a teacher, I can smell a homework question here).
I will not post the answer because I'd be doing your homework for you and we need good programmers in this world. If I (or anyone else) do your homework you'll never understand the basic concepts of programming, and never becoming a good programmer.
Now, building on top of smac89's comment:
Your code to reverse has an issue: it prints 0 after it reverses the digits. Why? because you are returning an integer and then printing it in your main function but you are not really using the return value anywhere else.
Try calling your method without the System.out.println in main and see what happens.
So, basically, evaluate if you really need to return an integer and, if you don't, you can now evaluate how you are calling the recursion (again, read smac89's comment).
I wish you the best in your studies!
You need to reduce the number by successive divisions first. Then process the values as they are unwound from the stack. This will print the most significant to least significant digit. Then return the starting number.
public static int digitShow(int num) {
if (num > 10) {
digitShow(num/10);
}
System.out.println(num%10);
return num; // returns the starting number.
}
prints
9
8
1
9
8
1
8
7
98198187

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.

What happens when recursion is called twice in a method?

I'm pretty new to programming and I have now come to the concept of recursion. I have solved a few basic assignments but when I come to multible recursion I get terribly lost. I have tried to solve the following recursion several times but just cant get it right.
A recursive method is called with the arguments "ABCD" and 2, i.e. recMethod("ABCD", 2);.
public void recMethod( String str, int n ) {
if( n >= 0 ) {
recMethod(str, n – 1);
System.out.print(str.charAt(n));
recMethod(str, n – 1);
}
}
Is there somebody out there who can explain what is going on? The first recursive call really confuses me.
The best way to understand recursion as for me is to write it on the paper line by line. What I did for your case now.
Please try to do the same, and don't hesitate to ask more question, I hope it helps!
The most important thing to know about recursion is that it's nothing special. As with everything in a method it needs to finish a statement before the next statement can be executed:
public void someMethod() {
someOtherMethod();
someLastMethod();
}
Looking at my example it's obvious that someLastMethod will be called after someOtherMethod has finished. It really doesn't matter if you replace someOtherMethod with something recursive. It needs to finish before someLastMethod can be called. When looking at your recursive method again:
public void recMethod( String str, int n ) {
if( n >= 0 ) {
recMethod( str, n – 1 );
System.out.print( str.charAt( n ) );
recMethod( str, n – 1 );
} else { // base case added for clarity
return;
}
}
For each call where n >= 0, before the System.out.print method is called the call to recMethod has to be called. Every call to recMethod has it's own n and str so they can be considered different methods entirely except their code is 'very similar'.
Every call will either match base case or need the result of the same method with n decremented so I like to start from the base case and work myself backwards, which is when n is -1. Imagine you call recMethod("ABCD",-1) what would happen? Well it prints nothing or "".
I then look at recMethod("ABCD",0) and it calls the base case, which we know does nothing, then prints "A" and then it calls the same as the first statement which again does nothing. Thus it prints "A"
If we look at recMethod("ABCD",1). We know it calls recMethod("ABCD",0) which prints "A", then it prints "B", then call recMethod("ABCD",0) which prints "A". Thus it prints "ABA"
If we look at recMethod("ABCD",2). We know it calls recMethod("ABCD",1) which prints "ABA", then it prints "C", then call recMethod("ABCD",1) which prints "ABA". Thus it prints "ABACABA"
If we look at recMethod("ABCD",3). We know it calls recMethod("ABCD",2) which prints "ABACABA", then it prints "D", then call recMethod("ABCD",2) which prints "ABACABA". Thus it prints "ABACABADABACABA"
Since "abcd".charAt(4) won't work it doesn't make sense to go on. Perhaps the code should have a test for this or perhaps it should be private and have a public one without n that guarantees n never goes beyond str bounds?
If you were to make a method that works recursively you do the same.
What should happen for the base case. (How should it stop)
What should happen if it's not the base case expressed as if the method works as intended. The catch here is that you need to make sure that each call to the same method here is a slightly simpler problem which the recursion is bound to hit a base case or else you get infinite recursion!
Thats it! It will work.

Confusion with string recursion base case (Java)

So for homework this weekend we're learning about recursion so that means the dreaded string reversal with recursion problems. I have a simple piece of code that is correctly performing the recursion (according to the debug mode in eclipse) but since (?? this is where I'm confused) I'm calling it from a a different area of the program, it just keeps going on infinitely until it crashes or overflows or whatever it's called.
public static void main(String[] args)
{
System.out.println(reversePrint("Hello"));
}
public static String reversePrint(String s)
{
if (s.length() <= 1)
return s;
return reversePrint(s.substring(1) + s.charAt(0));
}
I've been trying to Google-fu my way to figuring out why but I just can't, most sites explain recursion with pretty much the code I've written for the actual reversal of the string, but none seem to deal with any problems with getting it to print. I honestly don't know what I'm overlooking, been at this for a few hours, feels like I'm banging my head against a wall.
Try this:
public static String reversePrint(String s) {
if (s.length() <= 1)
return s;
return reversePrint(s.substring(1)) + s.charAt(0);
}
Here was the problem in your code:
reversePrint(s.substring(1) + s.charAt(0))
You kept calling the reversePrint() method with a string of the same size - and as you know, a recursion must "reduce" the problem at each step until it hits the base case, or else it will never end.
If you use reversePrint(s.substring(1) + s.charAt(0)), you always pass the full string into reversePrint.
You should make sure that the string passed to reversePrint is always getting smaller:
reversePrint(s.substring(1)) + s.charAt(0);
Notice how what I pass to reversePrint is one character smaller than s.
I Am Also Studying Recursion In Class Now, and The important Part Is To Remember Base Case And Proper Method Calls That Iterate Logically. Simple Syntax Errors Like Parentheses:
return reversePrint(s.substring(1) + s.charAt(0));
Won't Make Or Break It. Learning The Logic And Concept Of Recursion Is Much More Important. Stay Positive!

Recursion output ambiguity

Ok so i am just learning recursion and i am confused on one point.
This is the code
public class RecursiveDemo {
public static void showRecursion (int num) {
System.out.println("Entering method. num = " + num);
if (num > 1) {
showRecursion(num - 1);
}
System.out.println("Leaving method. num = " + num);
}
public static void main(String[] args){
showRecursion(2);
}
}
The output i am getting is :
Entering method. num = 2
Entering method. num = 1
Leaving method. num = 1
Leaving method. num = 2
My question is why am i getting the output "Leaving method. num = 2". Shouldn't it stop at "Leaving method. num = 1" since num has already reached 1?
Once the original invocation of this method leaves the if statement, it passes to System.out.println("Leaving method. num = " + num);. Since you invoked the message originally with value 2, 2 is the value of num for this part of the code.
Your code runs like this (pseudocode):
Start First Call
if statement
Start Second call
Skips if statement
Print from Second Call
End of Second Call
End of if Statement
Print From First Call
End of First Call
It looks like you have a fundamental misunderstanding of recursion.
When you call your method with (num-1) as arguments, the parent call (the first call, in this case), retains the value num as its argument, which is 2, in this case.
So let's comment out the line below
//showRecursion(num - 1);
What would you get? It must be
Entering method. num = 2
Leaving method. num = 2
And if you uncomment the line above. You should get the one you had.
No.
main will call showRecursion(2), which in turn will call showRecursion(1) (so you get two "Entering" messages). At which point, the condition will fail, so no more recursion occurs. So now the program simply begins returning from each function call in turn, printing both of the "Leaving" messages.
It's because the initial call to showRecursion(2) hasn't finished yet.
Consider the following:
public static void showFirstRecursion (int num) {
System.out.println("Entering method. num = " + num);
if (num > 1) {
showSecondRecursion(num - 1);
}
System.out.println("Leaving method. num = " + num);
}
public static void showSecondRecursion (int num) {
System.out.println("Entering method. num = " + num);
if (num > 1) {
showThirdRecursion(num - 1);
}
System.out.println("Leaving method. num = " + num);
}
// I won't bother showing an implementation for showThirdRecursion, because it won't be called.
public static void main(String[] args){
showFirstRecursion(2);
}
No problem here, right? You'd expect to see the first method entered, second entered, (third not entered because num == 0), second left, first left.
There is really nothing special about recursion. It's just making a function call that happens to be calling the function that the call is a part of. A recursive call behaves, conceptually, in all respects like any other function call. The trick is the design of a recursive algorithm, i.e., coming up with a reason why you'd want to call the same function you're already in.
The other answers already cover the specific question, but here is some information on using a debugger. This tutorial is for Eclipse, but pretty much tells you what you need to know for any visual debugger.
The basics are pretty straightforward, and it would be well worth your time to at least learn how to step through the code. A debugger is an invaluable tool for quickly verifying the logic of your program, and is far easier than scattering print statements everywhere.
Try "showRecursion(5);".
[Answer: This is recursion. There's more than one copy of the variable "num" in memory. "num" is a parameter; it's not a field, and it's not static.]
So what I understood was
with every method call, Stack is getting populated ie. 2,1
but when i>1 doesn't matches it returns/breaks the call and control is given to the system.out.println line, that prints the value starting from the top of stack ie 1,2

Categories

Resources