Ok, so I have a program:
public class Rec {
public static void main(String[] args) {
test(5);
}
static void test(int n) {
if (n > 0) {
System.out.println(n);
test(n-1);
System.out.println(n);
}
}
It's output is 5,4,3,2,1,1,2,3,4,5. My question is, why/how does the second println(n) statement get executed? I thought that the function call would completely cut it off, instead it acted in a way that baffles me. This isn't homework or anything, I just really am having a hard time understanding how recursion works.
All method calls return to the same place once they are done.
By effectively chaining them you get
System.out.println(5)
System.out.println(4)
System.out.println(3)
System.out.println(2)
system.out.println(1)
// If is not true now.
System.out.println(1)
System.out.println(2)
System.out.println(3)
System.out.println(4)
System.out.println(5)
Does that make sense?
When your test method terminates, it'll resume in the same place it was in the stack frame above.
For example, if I had some code:
public class Test {
public static void main(String[] args) {
System.out.println("A");
myFunc();
System.out.println("B");
}
public static void myFunc() {
System.out.println("Do something here");
}
}
...you'd expect both printlns inside main to run, since myFunc terminates/doesn't enter an endless loop.
That's true, even if you're using recursion. Your test method will eventually terminate, so that means that the second println must be executed at some point in time.
In contrast, imagine we had a "recursive" function which never terminates:
public class Test {
public static void main(String[] args) {
test2(5)
}
public static void test2(int n) {
System.out.println("A " + n);
test(n - 1);
System.out.println("B " + n);
}
}
Because the test2 method never terminates, there's absolutely no way for the second println to execute. It's for this reason why you should always design any recursive function so that it can terminate when some condition is reached.
Concept of stack is very important if we were to understand a recursion. Stack is A LIFO data structure. Remember whenever a method call happens the current state is pushed into the stack (Current state involves the values of local variables , address of next executable statement etc). Now lets see your problem.
First this happens,
System.out.println(5);
test(n-1); // method call is happening so store state to stack !!!
//stack contents: n=5 and address of next statement
System.out.println(4);
test(n-1);//another state added to stack : n =4
System.out.println(3);
test(n-1);//another state added to stack: n = 3
System.out.println(2);
test(n-1);//another state added to stack : n = 2
System.out.println(1);
test(n-1);//another state added to stack : n = 1
Now the condition if(n>0) fails now returning phase of recursion happens i.e, the control goes back to the state from which the call was made, and remember all the states were stored in stack and also remember stack is LIFO so now:
// n = 1 first state in stack
System.out.println(1);
//n = 2 second state stored in stack
System.out.println(2);
//n = 3 third state stored in stack
System.out.println(3);
//n = 4 fourth state stored in the stack
System.out.println(4);
//n = 5 last state stored in stack
System.out.println(5);
Now all the calls are completed and the control goes back to main.
Please look your code:
static void test(int n) {
if (n > 0) {
System.out.println(n);
test(n-1);// this makes the new call to method test() and causes the state to be stored in the stack
System.out.println(n);// this statement doesn't execute until the recursive call made to test() doesn't return .
}
HTH :)
To assume that your expected result should be "54321", your problem is your second
System.out.println(n);
The first part of your test-method does exactly what you want it to do:
if (n > 0) {
System.out.println(n);
test(n-1);
// System.out.println(n);
}
The result would be "54321" - fantastic!
But what happens, because of the second println-method at the end of your test-method, is that you are stacking you output actually (as Crazy Programmer already showed us really precisley). In other words: you don't need the second println-method at all to reach your goal! And that's the wonderful thing about recursion: it "breaks" when calling test() again, leaving your second println-method "not executed by now" and starts the whole process again.
What you propably don't see is, that by using
if (n > 0)
you are verifying that n is greater than 0 (so at least 1), while (at the same time) this is your break condition too! So what your method actually has to do is:
check, if n is greater than 0,
print the value of n, and (at last)
call test-method again (with n-1)
If n reaches 0, the whole "method-stacking" dissolves itself (have a look at Niels' solution) and wont return you any further n-values. Got it?
The method is still existing after the recursive call to itself. Once those calls are dealt with, the method will come back to execute the remaining lines of code.
Have a look at this : http://ideone.com/zWqP8h
public static void main(String[] args) {
test(5);
}
static void test(int n) {
if (n > 0) {
System.out.println("First step :" + n);
test(n-1);
System.out.println("Second step :" + n);
}
}
Probably it will help to clarify things.
I think you should trace code then you will get solution.
your code trace something like this. try to debug this lines this might help you.
//for n = 5
void test(int n) {
if (n > 0) {
System.out.println(n);
test(n-1);----->// call of same function
//for n = 4
void test(int n) {
if (n > 0) {
System.out.println(n);
test(n-1);----->
//for n = 3
void test(int n) {
if (n > 0) {
System.out.println(n);
test(n-1);---->
//for n = 2
void test(int n) {
if (n > 0) {
System.out.println(n);
test(n-1);---->
//for n = 1
void test(int n) {
if (n > 0) {
System.out.println(n);
test(n-1); ---->
//for n = 0
void test(int n) {
if (n > 0) {//not satisfy
System.out.println(n);
test(n-1);
System.out.println(n);
}
// Till hear you were right but next things you missed.
}//again resume of n = 1
System.out.println(n);
}
}//again resume of n = 2
System.out.println(n);
}
}//again resume of n = 3
System.out.println(n);
}
}//again resume of n = 4
System.out.println(n);
}
}//again resume of n = 5
System.out.println(n);
}
}//Finish recursion.
Related
So, the following recursive function in C:
void print(int n){
if(n==1){
printf("ab");
return;
}
putchar('a');
print(n-1);
putchar('b');
}
will give you the output: aaabbb if n=3.
But, i tried to 'translate' this into Java and came up with a problem.
my code in Java looks like this: (which is pretty similar)
public static void printAB(int n){
if (n==1) {
System.out.println("ab");
}else {
System.out.print("a");
printAB(n-1);
System.out.print("b");
}
}
but the output i'm getting is this:
aaab
bb
no matter what i tried i couldn't fix the last 2 'b' to be in the same line.
help please?
Change:
System.out.println("ab");
to:
System.out.print("ab");
so there is no newline printed.
Full Code:
public static void printAB(int n) {
if (n == 1) {
System.out.print("ab");
} else {
System.out.print("a");
printAB(n - 1);
System.out.print("b");
}
}
Output for printAB(3):
aaabbb
Sorry I am having a mental block, can anyone see why I get the 'cannot convert from int to boolean' error message. Much appreciated
public static void main (String[]args) {
int max=10;
int sum=0;
int count=0;
for(int counter=0;counter=max-4;counter++) {
sum=max-4;
count=max-3;
for(sum=3;sum<5;sum++) {
if(count==0 && max>0){
System.out.println("Hello");
} else if (count<4) {
System.out.println("Go for it");
} else {
System.out.println("OK");
}
}
}
sum=sum+count;
System.out.println("Total = "+sum);
System.out.println("Max = "+count);
}
I feel like I have checked using the '==' for the if condition.
= is assignment, you need a comparison in the second term of your loop.
for(int counter=0;counter=max-4;counter++) {
should be
for (int counter = 0; counter < max - 4; counter++) {
(white space added, but note < is a comparison... perhaps you wanted <=).
In case of Java, the syntax of for loop is
for(initialization; Boolean_expression; update) {
// Statements
}
1) The initialization part executes only once when the flow enters the for loop for the first time
2) Next, the boolean expression is resolved according to the condition
3) Then next the update statement is resolved and after execution of the body of the for loop again the flow goes to the boolean expression and then update statement and the flow goes on.
So, In your program instead of a boolean expression, you have used an assignment operator which turns out to be 6 which is not 0 or 1. Boolean expression are true = 1 and false = 0. Hence the integer 6 cannot be converted to boolean. So, you can go with counter < max-4
I'm currently trying to use a function that compares the left and right side character to return a true or false Boolean value as to whether the string entered by the user is a palindrome or not, but I get a vague error statement to do with line 44. Not sure how to proceed. I am a beginner-level Java programmer who is open-minded and willing to learn, so don't roast me to hard haha.
import java.util.Scanner;
/**
*
* #author owner
*/
public class Q2_RecursivePalidrome {
public static void main(String[] args) {
int leftSideCharacter = 0;
int rightSideCharacter = 0;
Scanner scan = new Scanner (System.in);
System.out.println("Enter word to check whether palidrome: ");
String userInput = scan.next();
char[] checkPalidrome = userInput.toCharArray(); // creates an array of characters
System.out.println(isPalidrome(checkPalidrome, leftSideCharacter, rightSideCharacter));
}
public static boolean isPalidrome(char[] checkPalidrome, int leftSideCharacter, int rightSideCharacter) {
leftSideCharacter = 0;
rightSideCharacter = checkPalidrome.length - 1; // java arrays start at 0, not 1.
if (rightSideCharacter > leftSideCharacter) { // check both ends of string character by character
// to be palidrome, both sides of string should be same
//
if (checkPalidrome[leftSideCharacter] == checkPalidrome[rightSideCharacter]) {
return (isPalidrome(checkPalidrome, leftSideCharacter + 1, rightSideCharacter - 1));
}
else {
return false;
}
}
return true;
}
}
There are a couple main issues here, but you have the right idea:
Your recursive function uses left and right indices to determine which characters to compare in the test string. However, these two pointers are immediately set to the left and right ends of the string when the function is called, so they never recursively move towards the middle. Since the base case where the indices are equal is unreachable, the stack overflows. Remember, these calls are identical all the way down the stack, but with different parameters, so one-time "set up" tasks like setting initial indices should be moved outside of the recursive function.
Your initial pointer indices are 0, 0. This is an inaccurate "set up" call to the recursive function--it should be 0, string.length - 1.
Here is code that fixes these problems and cleans up comments and variable names:
import java.util.*;
public class Q2_RecursivePalidrome {
public static void main(String[] args) {
String test = "racecar";
System.out.println(isPalidrome(test.toCharArray(), 0, test.length() - 1));
}
static boolean isPalidrome(char[] test, int l, int r) {
if (l < r) {
if (test[l] == test[r]) {
return isPalidrome(test, l + 1, r - 1);
}
else {
return false;
}
}
return true;
}
}
By the way, the important lesson to take from all this is how to debug your program. In this case, printing your indices (the arguments that change from one call to the next) at the top of your recursive function will clearly show that they aren't doing what you expect.
I want to know how recursive method work to prints a large X composed of smaller X's with a given “width”, input number, which is guaranteed to be odd.
the “width” is length (number) of X’s along one line large X.
Example for an X of width input number =3
the method will print this shape!
X X
X
X X
I try to solve this problem but I couldn't
can anyone here help me ..
in java code ,
This is my code he works good but prints wrong when numberinput=7 or 5
public static String shape(String i,int numberinput) {
//error check, not working for even numbers
if(numberinput%2 == 0)
return null;
//terminating condition, stop recursion when this occurs.
if(numberinput == 1)
return "X";
else
return "X"+" "+i+"\n" +" "+shape(" "+i,numberinput-2)+" "+"\n"+i+" "+"X";
}
he prints this when numberinput=5
X X
X X
X
X X
X X
A valid recursive method should have two parts.
Recursive call (call itself to do part of work)
Terminating condition (A condition to stop the recursion)
You have a recursive call, but not a termination condition. Hence your recursion won't stop until it fills up the entire stack and cause an exception. Hence you should include a terminating condition in your recursive method.
A sample implementation might look like this.
public static String shap(String i, int numberinput) {
//error check, not working for even numbers
if(numberinput%2 == 0)
return null;
//terminating condition, stop recursion when this occurs.
if(numberinput == 1)
return "X";
//recursion, call recursive until terminating condition occurs.
return "X" + i + shap(i, numberinput-2) + i + "X";
}
I have written a java code, in which recursion is only for the levels, to generate the string i have used a loop :
import java.util.*;
import java.lang.*;
import java.io.*;
public class Main
{
public static void main (String[] args) throws java.lang.Exception
{
List<String> ans = new ArrayList<String>();
shap(7, 1, ans);
//System.out.println(ans);
for(int i = 0;i < ans.size();i++){
System.out.println(ans.get(i));
}
}
public static void shap(int numberinput, int currentLevel, List<String> ans) {
if(currentLevel == numberinput+1) return;
String val = "";
for(int i = 1;i <= numberinput;i++){
if(i == currentLevel || i == (numberinput+1-currentLevel)) val += "X";
else val += " ";
}
ans.add(val);
shap(numberinput, currentLevel+1, ans);//Recursion step for the levels
}
}
Link to solution on Ideone : http://ideone.com/RioL9g
I am currently learning the basics of Java from a book and I've got this code as an example of Nested Loops using Recursion. I understand everything, but the usage of return function in the end of the code. I cannot figure out how the program decide, when to stop exactly when K=4. I've tried to debug it and this continued to be like a mystery for me. Here is the code :
import java.util.Scanner;
public class nestedLoops {
public static int numberOfLoops;
public static int numberOfIterations;
public static int[] loops;
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("N = ");
numberOfLoops = input.nextInt();
System.out.print("K = ");
numberOfIterations = input.nextInt();
input.close();
loops = new int[numberOfLoops];
nestedLoops(0);
}
public static void nestedLoops(int currentLoop) {
if (currentLoop == numberOfLoops) {
printLoops();
return;
}
for (int counter=1;counter<=numberOfIterations;counter++) {
loops[currentLoop] = counter;
nestedLoops(currentLoop + 1);
}
}
public static void printLoops() {
for (int i = 0; i < numberOfLoops; i++) {
System.out.printf("%d ", loops[i]);
}
System.out.println();
}
}
It would be very helpful if someone explain me how return works in this particular example in the end when numbers are "4.4" and also how it works at all in a void method, because I've been searching for explanation of that but did not succeed...
Thank you beforehand !
A return statement in a void method stops running the method and returns back to the calling code. In this example with the input:
numberOfLoops = 4
numberOfIterations = 4
Right after taking the input, you create an array based off of the input and then call the nestedLoops(0) method:
public static void nestedLoops(int currentLoop) {
if (currentLoop == numberOfLoops) {
printLoops();
return;
}
for (int counter=1;counter<=numberOfIterations;counter++) {
loops[currentLoop] = counter;
nestedLoops(currentLoop + 1);
}
}
The explanation
For starts, let's just ignore the for loop. The if statement checks to see if currentLoop == numberOfLoops and it does this every time this method is called. Right now currentLoop is 0 (the value we passed into this method when we called it) and numberOfLoops is 4 (the value we entered at the very beginning) so this is false and none of the code inside is called.
The for loop below the if statement is going to run numberOfIterations times. In our case, this loop is going to run 4 times. I will write out what happens below in sequential order:
- input is 4, 4
- nestedLoops(0) called- currentLoop = 0
- if evaluates to false
- for loop runs
- loops[0] = 1
- nestedLoops(1)
- if evaluates to false ( 1 != 4)
- for loop runs
- loops[1] = 1
- nestedLoops(2)
- if evaluates to false (2 != 4)
- for loop runs
- loops[2] = 1
- nestedLoops(3)
- if evaluates to false (3 != 4)
- for loop runs
- loops[3] = 1
- nestedLoops(4)
- if evaluates to TRUE (4 == 4)
- loops are printed (all values are 1 right now)
-returns to calling location
-Which is the for loop associated with this indention.
-For loop increments, and then sets loops[3] = 2.
- then this loop finishes
- then this loop finishes
etc. etc.
The return in a void method just means "okay, stop what you're doing and go back to who/whatever called this and move on" In this case its jumping back to previous for loop to keep working.
The for loop inside the nestedLoops method is calling itself numberOfIterations times. So it goes 0, then makes numberOfIterations calls. So if you entered 4 you would see 4 calls with currentLoop=1 then 16 calls with currentLoop=2 and so on....
When all else fails write some code to debug your code. I am a visual person myself so making some output helps when the debugger doing it for me.
public static HashMap<Integer, Integer> map = new HashMap();
public static void main(String[] args) {
....
System.out.println(map);
}
public static void nestedLoops(int currentLoop) {
if(map.containsKey(currentLoop)) {
map.put(currentLoop, map.get(currentLoop)+1);
} else {
map.put(currentLoop, 1);
}
...
}