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.
Related
Doing a very simple program to test out recursion. The program prints something until the number is not greater than 0.
public class TestIt {
public static void print(int f){
while(f>0){
System.out.println("Not today");
f--;
print(f);
}
}
}
the code above is called from the main program like this.
public static void main(String[] args) {
TestIt.print(2);
}
Maybe I'm finally losing my mind, but the amount of times the program prints is exceeding what I expected. If I send 3 to the method then the program prints 7 times. Any ideas as to why?
Because you did wrong
while(f>0){
System.out.println("Not today");
f--;
print(f);
}
you are calling the method print f in the loop times
and as it is recursive it will be called f-1 times recursivelly
so it will b f fatorial times
remove the while loop and will work as you want
This is because everytime the call comes off the stack, f is still what it was originally, and then it continues with the while loop. So for 2:
while(f>0){
System.out.println("Not today");
f--;
print(f);
}
First run, subtracts from 2, results in one. (Print count = 1) Resursive call:
Subtracts again, 0, recursive call: (Print count 2)
While loop is never entered. returns:
0, while loop is not executed, reuturns:
While loop is run again, recursive call: (print count = 3)
Passes zero, while loop not entered, return
While loop terminated, exit method
For 2 it prints three times, but this grows for every number passed in. To fix this do:
if(f>0){
System.out.println("Not today");
f--;
print(f);
}
Remember recursion usually is to avoid loops, so if you find yourself using both, this is usually a red flag
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.
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).
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
My job is to write a recursive version to this method. From what I understand Recursion is starting with a base call (if something then return) followed by an else which unwinds back to the original base. Like starting with a deck, adding on to the deck then removing cards from the deck until you are back to the original deck.
With that in mind here it is.
public static long fact(int n)
{
long result = 1;
while(n > 0)
{
result = result * n;
n = n - 1;
}
return result;
}
//my recursive version:
public static void recFact(int n)
{
if(n==0)
{
return n; // ir 0 it really doesn't matter right?
}
else
{
return recFact(n-1);
}
}
This is just an example test problem for an exam I have coming up, just want to make sure I have a handle on recursion. Did I do this right? If not what am I missing? please no answers in questions, just tell me what I did wrong and maybe some advice on better ways to understand it.
Thanks.
No, this recursive solution is not correct.
For every positive n, you're just return rectFact(n-1), which will recourse until you reach 0, at which point it will return. In other words, your function will always return 0. You're missing the part where you multiply the current n with rectFact(n-1). Additionally, note that 0! is 1, not 0:
public static int recFact(int n)
{
if(n==0)
{
return 1;
}
else
{
return n * recFact(n-1);
}
}
And finally, since the if clause returns, the else is somewhat redundant. This doesn't affect the method's correctness, of course, but IMHO the code looks cleaner without it:
public static int recFact(int n)
{
if(n==0)
{
return 1;
}
return n * recFact(n-1);
}
Your recursive version does no multiplication, and it will return zero for any input. So no, you didn't do it right.
But, the recursive version DOES recurse, so you have that going for you! To understand what's going wrong, walk through a very simple case.
Client calls recFact(3)
This will return to client recFact(2)
Which will return to above recFact(1)
Which will return to above recFact(0)
Which will return to above 0.
There are two major things going wrong:
Your base case is wrong (zero is too low)
You're not doing any multiplication
Good attitude about not wanting the solution handed to you! Hopefully these pointers wil help you figure it out.
EDIT: Apparently I misunderstood your grammar and you did want the solution.
Any recursive function needs three things:
The terminating condition: This tells the function when to stop calling itself. This is very important to avoid infinite recursion and avoid stack overflow exceptions.
The actual processing: You need to run the actual processing within each function. In your non recursive case, this was result = result * n. This is missing from your recursive version!
A collector/agggregator variable: You need some way to store the partial result of the recursive calls below you. So you need some way to return the result of recFact so that you can include it in processing higher up in the call chain. Note that you say return recFact(n - 1) but in the definition recFact returns void. That should probably be an int.
Based from your example you are missing the return type of your recFact which is int
Also recFact will always return 0 because you are not multiplying n each time to the recursion call of the method.
There are two ways to write recursive routines. One is the "standard" way that we all are taught. This is one entry point that must first check to see if the recursive chain is at an end (the escape clause). If so, it returns the "end of chain" value and ends the recursion. If not at the end, it performs whatever calculation it needs to get a partial value according to the level and then calls itself passing a value the next increment closer to the end of the chain.
private final int InitialValue = 15;
System.out.println( "Fact(" + InitialValue + ") = " + recFact( InitialValue ) );
public int recFact( int val ){
if( val < 2 ){
return 1;
}
else{
return recFact( val - 1 ) * val; // recursive call
}
}
//Output: "Fact(15) = 2004310016"
In regular recursion, a partial answer is maintained at each level which is used to supplement the answer from the next level. In the code above, the partial answer is val. When first called, this value is 15. It takes this value and multiplies it by the answer from Fact(14) to supply the complete answer to Fact(15). Fact(14) got its answer by multiplying 14 by the answer it got from Fact(13) and so on.
There is another type of recursion called tail recursion. This differs in that partial answers are passed to the next level instead of maintained at each level. This sounds complicated but in actuality, make the recursion process much simpler. Another difference is that there are two routines, one is non recursive and sets up the recursive routine. This is to maintain the standard API to users who only want to see (and should only have to see)
answer = routine( parameter );
The non-recursive routines provides this. It is also a convenient place to put one-time code such as error checking. Notice in the standard routine above, if the user passed in -15 instead of 15, the routine could bomb out. That means that in production code, such a test must be made. But this test will be performed every time the routine is entered which means the test will be made needlessly for all but the very first time. Also, as this must return an integer value, it cannot handle an initial value greater than 19 as that will result in a value that will overflow the 32-bit integer container.
public static final int MaxFactorialSeq = 20;
private final int InitialValue = 15;
System.out.println( "Fact(" + InitialValue + ") = " + recFact( InitialValue ) );
public int recFact( int value ){
if( value < 0 || value > MaxFactorialSeq ){
throw new IllegalArgumentException(
"Factorial sequence value " + value + " is out of range." );
}
return recFact( value, 1 ); // initial invocation
}
private int recFact( int val, int acc ){
if( val < 2 ){
return acc;
}
else{
return recFact( val - 1, acc * val ); // recursive call
}
}
//Output: "Fact(15) = 2004310016"
Notice the public entry point contains range checking code. This is executed only once and the recursive routine does not have to make this check. It then calls the recursive version with an initial "seed" of 1.
The recursive routine, as before, checks to see if it is at the end of the chain. If so, it returns, not 1 as before, but the accumulator which at this point has the complete answer. The call chain then just rewinds back to the initial entry point in the non-recursive routine. There are no further calculations to be made as the answer is calculated on the way down rather than on the way up.
If you walk though it, the answer with standard recursion was reached by the sequence 15*14*13*...*2*1. With tail recursion, the answer was reached by the sequence 1*15*14*...*3*2. The final answer is, of course, the same. However, in my test with an initial value of 15, the standard recursion method took an average of 0.044 msecs and the tail recursion method took an average of 0.030 msecs. However, almost all that time difference is accounted for by the fact that I have the bounds checking in my standard recursion routine. Without it, the timing is much closer (0.036 to 0.030) but, of course, then you don't have error checking.
Not all recursive routines can use tail recursion. But then, not all recursive routines should be. It is a truism that any recursive function can be written using a loop. And generally should be. But a Factorial function like the ones above can never exceed 19 levels so they can be added to the lucky few.
The problem with recursion is that to understand recursion you must first understand recursion.
A recursive function is a function which calls itself, or calls a function which ultimately calls the first function again.
You have the recursion part right, since your function calls itself, and you have an "escape" clause so you don't get infinite recursion (a reason for the function not to call itself).
What you are lacking from your example though is the actual operation you are performing.
Also, instead of passing a counter, you need to pass your counter and the value you are multiplying, and then you need to return said multiplied value.
public static long recFact(int n, long val)
{
if(n==1)
{
return val;
}
else
{
return recFact(n-1, val) * n;
}
}
Code:
public static char f( char c ){
System.out.print( c++ );
return c--;
}
public static void main(String[] args)
{
if( f('j') == 'k' || f('f') == 'f'){
System.out.println( f('d') );
}
}
Can someone please explain to me why this prints "jde"??
Intuitively, I thought it would print "kged".
The value of the expression c++ is the value of c BEFORE it gets incremented. And the value of the expression c-- is the value BEFORE it gets decremented.
So in the first call to f in your example, c starts off as 'j'. Then the line System.out.println(c++); prints 'j' and increments c, so that it's now k. On the next line, it returns the new value of c, which is 'k'.
Since the first half of the if condition is true, the second half is not evaluated. We jump straight into the body of the if. But this works the same way as before - it prints 'd' and returns 'e'. The 'e' is then printed.
c++ is incremented after the System.out.print, so it prints 'j' first.
The second part of the if statement is not evaluated since f('j') returns 'k' as the decrement is applied after the return.
Then d is printed because f('d')' is called which first prints 'd' and then the result of the function 'e'.
If you want to understand why a problem is doing something, especially if it is rather unexpected, it is a good idea to get familiar with a debugger. With that you can step through every instruction, and see the state of your program at every execution step.
As an exercise, write a program which is using those functions, but prints qed (quod erat demonstrandum).
In the if condition is f('j')=='k' which is true and that is why other condition is not being checked. Here f('j') methods prints j and returns 'k' and after returning c is again 'j'. Now in System.out.println(f('d')); f('d') prints d and returns e which is printing in main method. So the output is jde