How do I count up using recursion in Java? - java

So, I'm auditing a Java course on EdX and have been doing really well up until this point. I've come to recursions and one of the tasks is to create a method that counts up to a specified number placing commas between each (i.e. System.out.println(writeNum(5)); should print "1, 2, 3, 4, 5, ... n" with no comma on the final number).
Additionally, there's supposed to be an IllegalArgumentException should a value less than 1 be passed.
I've been on it for 2 days wracking my brain and I cannot even comprehend how to start. I can do the factorial one :
public static int factorial (int n) {
if(n == 1){
return 1;
}
System.out.println(n);
return n*factorial(n-1);
}
No problems right? So, thinking about it I keep thinking, what is the base case? Is it 1? if so, then I'm just counting down and somehow need to count down, reorganize them, reprint them, then somehow figure it out that way. Or, I make my base case when n==n, which doesn't work either... I know I am probably overthinking this, but I have no idea how to even get it started... If anyone could go through it with me step by step to understand this, I would sincerely be grateful as I'm doing this because I genuinely want to learn and understand this stuff.

For recursion, you need to find when to return e.g. in the code given below, when n == 1, the method prints the value of n and returns. Apart from the terminating condition, another important aspect is where (i.e. whether before calling the method/function recursively or after it) you process (e.g. print) the parameter.
public class Main {
public static void main(String[] args) {
count(5);
}
static void count(int n) {
if (n == 1) {
System.out.print(n);
return;
}
count(n - 1);
System.out.print("," + n);
}
}
Output:
1,2,3,4,5
This is how it works:
count(5) -> calls count(4) with remaining thing to do is print ,5 once count(4) returns.
count(4) -> calls count(3) with remaining thing to do is print ,4 once count(3) returns.
count(3) -> calls count(2) with remaining thing to do is print ,3 once count(2) returns.
count(2) -> calls count(1) with remaining thing to do is print ,2 once count(1) returns.
count(1) -> prints 1 and returns.
The remaining thing of count(2) is done i.e. ,2 is printed.
The remaining thing of count(3) is done i.e. ,3 is printed.
The remaining thing of count(4) is done i.e. ,4 is printed.
The remaining thing of count(5) is done i.e. ,5 is printed.
Check this to learn more about recursion.

Related

Java method executes last print statement three times even though the method is only called once

I'm trying to figure out why this mystery method in Java prints out "43211234". I understand how the program reaches "43211" but I'm not sure how the last System.out.print(x % 10) after the "if" is ran 3 times and for each time, it brings the value of x back to the value it was previous to its current one until it reaches "1234" as the value of x. Could this have something to do with recursion since the method is being called in the "if" 3 times? I'm guessing it's something along those lines because the last executes exactly 3 times as well. I would greatly appreciate your help. Thanks.
class Main {
public static void main(String[] args) {
mystery(1234);
}
public static void mystery(int x) {
System.out.print(x % 10);
if((x / 10) != 0) {
mystery(x / 10);
}
System.out.print(x % 10);
}
}
Not sure if my answer will be any more useful than the previous ones, but I'll try. So, basically, your program uses 2 types of recursion: backward recursion and forward recursion. My answer here is not to describe them to you, but to give you a starting point for more information on them.
Let's trace your program's execution:
mystery(1234) -> print(4) -> mystery(123); At this point, the System.out.print(x % 10); at the end of the method has not been called yet since your program has gone further in the recursion. It will be executed once the program returns from deep inside your recursion, and will be executed with whatever's left.
mystery(1234):
print(4);
mystery(123):
print(3);
mystery(12):
print(2);
mystery(1);
print(1);
print(1); //This is the first System.out.print(x % 10); from the end of the method, that is executed
print(2);
print(3);
print(4);
I understand how the program reaches "43211"
so you know what recursion is.
Everytime mystery() is called, the 1st print is called and then it calls (recursively) itself, before the 2nd print.
When the recursion stops because (x / 10) != 0 is false, the 2nd print is called for the 1st time and then goes back to the previous unfinished recursive calls and executes the remaining print for each one.
Your mystery() method does the following:
print the final digit of the input number (num % 10 gives the last digit)
make a recursive call mystery(x / 10), assuming x / 10 is not zero
then on the way out from the recursion, print the final digit of the input again
Putting this together, with an input of 1234, it means we would print those digits in reverse, then print them again in order.
If this answer still leaves you with doubts, I suggest running your code, beginning with a two digit input like 12, until it is clear what is happening.
This is your recursion stack. This is perfectly fine.
mystery(x / 10); input 1234 prints 4
-> mystery(x / 10); input 123 prints 3
-> mystery(x / 10); input 12 prints 2
-> mystery(x / 10); input 1 prints 1
Just make sure your remove the second sysout that you that you in your code. That is the reason it is printing the same numbers in again.

Towers of Hanoi recursive/iterative hybrid

I have to make a iterative solution to the Towers of Hanoi problem. I am trying to convert a tail recursive call to an iterative one. I am following an algorithm I found in my textbook to transform it. I followed this algorithm and even though my code is similar to the recursive variant my output doesn't match the designated form. Now from what the book tells me, having a recursive call with an iterative is strange, but valid.
public class DemoIterative
{
public static void TowersOfHanoi(int numberOfDisks,
String startPole, String tempPole, String endPole)
{
while (numberOfDisks > 0)
{
/** MUST GO 1, 3, 2, 1 */
TowersOfHanoi(numberOfDisks - 1, startPole, endPole, tempPole);
System.out.println(startPole + " -> " + endPole);
numberOfDisks = numberOfDisks - 1;
startPole = tempPole;
tempPole = startPole;
}
}
public static void main(String[] args)
{
DemoIterative demoIterative = new DemoIterative();
System.out.println("Enter amount of discs: ");
Scanner scanner = new Scanner(System.in);
int discs = scanner.nextInt();
demoIterative.TowersOfHanoi(discs, "A", "B", "C");
} // end of main
} // end DemoIterative
Now the output I am getting from this is:
A to C,
A to B,
C to B,
A to C,
B to B,
B to C,
B to C
I should be getting this (tested from recursive original):
A to C,
A to B,
C to B,
A to C,
B to A,
B to C,
A to C
This is the algorithm I am using:
While numberOfDisks is greater than 0, move disk from startPole to endPole, numberOfDisks--, exchange the contents of tempPole and startPole.
Now is this possible? If so, is there a problem with my algorithm or am I printing it wrong?
You have a problem with your algorithm. Most important for your own understanding of this, slap a print statement at the top of your routine and print out the arguments. Also insert one at the bottom of the loop to help track that execution.
To summarize, I don't think you understand the call tree you've created, and I think you should trace it to see. There are applications that will use such a tree, but I don't think that this what you want for this assignment.
There area couple of structural problems. For one, when you get to the bottom of the loop, you set startPole = tempPole, and follow that with a useless assignment back -- this wipes out the old startPole value; it does not exchange them.
Next, your loop + recursion structure is strange. First, you've used a while loop where the semantics clearly indicate a for -- you know how many times you'll iterate when you enter the loop. When you first call this with, say, 5 disks, the numberOfDisks (I'll call it N) = 5 iteration will loop 5 times. Each iteration recurs with N = 4, 3, 2, 1, respectively.
Now, the N=4 instance will do likewise: recurring with N=3, 2, 1. This gives you two instances at N=3. Continuing, you'll get three instances at N=2, and four at N=1, for a total of 11 calls to your function. Since only four of these involve moving a one-disk stack (for a tower of 5 disks, you need several more), I think you've incorrectly implemented whatever you had in mind.

understanding a simple recursion method

I'm starting to learn about recursion and how it can be used to solve problems.
The question is, what does the method call recur(4) display?
public static void recur (int n)
{
if(n==1)
{
System.out.print(n);
}
else
{
System.out.print(n);
recur(n - 1);
}
}
since n does not equal 1, it resorts to recur(n - 1) but this is where I am confused as to what happens here? Would the output be something along the lines of 3,2,1,0?
It will print: 4321.
If you call recur(4), then n == 4 when you start. It is not 1, so it goes to the else block, where it prints a 4, and then calls recur(3) (4-1 = 3). After that, it still isn't 1, so once again you go to the else block. This time n == 3, so 3 is printed out. Then recur(2) is called, which once again goes to the else block, printing out 2 and calling recur(1). n is equal to 1 now, so the if block is executed, which simply prints 1.
Note that you get 4321 as you have a System.out.print() statement, with no spaces. A println() would put it on a new line everytime, and you'd get:
4
3
2
1
But with a print() statement and no spacing, you'll simply get 4321

Java Homework Help - Recursion with array

I've got a set of recursion problems that I need to do. I've completed 3 out of the 4 of them we were given, but I'm having a hard time wrapping my head around this last one. I don't necessarily want the actual answer, but maybe just point me in the right direction, because I'm not even seeing what my stop condition should be on this one. And note, it has to be recursive, no loops, etc.
Thanks in advance for any help provided!
Write recursive method arrayRange that returns the maximum integer minus the minimum integer in the filled array of ints. Use recursion; do not use a loop. The following assertions must pass (note the shortcut way to pass a reference to a new array--it saves your writing a bit of code (this passes an array built as a parameter):
assertEquals(2, rf.arrayRange(new int[] { 1, 2, 3 } ));
assertEquals(2, rf.arrayRange(new int[] { 3, 2, 1 } ));
assertEquals(0, rf.arrayRange(new int[] { 3 } ));
assertEquals(3, rf.arrayRange(new int[] { -3, -2, -5, -4 } ));
// Precondition: a.length > 0
public int arrayRange(int[] a)
The stop condition is when there are only two items left: the maximum and minimum. Then just return the difference. (Also handle the case of 1 or 0 items, consider input such as in the test cases.)
Now .. how to reduce the list each pass? :) I would consider inspecting the first three values at a time (of the three, only two should remain in the recursive step).
Happy homeworking.

How does the recursion here work?

Code 1:
public static int fibonacci (int n){
if (n == 0 || n == 1) {
return 1;
} else {
return fibonacci (n-1) + fibonacci (n-2);
}
}
How can you use fibonacci if you haven't gotten done explaining what it is yet? I've been able to understand using recursion in other cases like this:
Code 2:
class two
{
public static void two (int n)
{
if (n>0)
{
System.out.println (n) ;
two (n-1) ;
}
else
{
return ;
}
}
public static void main (String[] arg)
{
two (12) ;
}
}
In the case of code 2, though, n will eventually reach a point at which it doesn't satisfy n>0 and the method will stop calling itself recursively. In the case of code 2, though, I don't see how it would be able to get itself from 1 if n=1 was the starting point to 2 and 3 and 5 and so on. Also, I don't see how the line return fibonacci (n-1) + fibonacci (n-2) would work since fibonacci (n-2) has to contain in some sense fibonacci (n-1) in order to work, but it isn't there yet.
The book I'm looking at says it will work. How does it work?
Well, putting aside what a compiler actually does to your code (it's horrible, yet beautiful) and what how a CPU actually interprets your code (likewise), there's a fairly simple solution.
Consider these text instructions:
To sort numbered blocks:
pick a random block.
if it is the only block, stop.
move the blocks
with lower numbers to the left side,
higher numbers to the right.
sort the lower-numbered blocks.
sort the higher-numbered blocks.
When you get to instructions 4 and 5, you are being asked to start the whole process over again. However, this isn't a problem, because you still know how to start the process, and when it all works out in the end, you've got a bunch of sorted blocks. You could cover the instructions with slips of paper and they wouldn't be any harder to follow.
In the case of code 2 though n will eventualy reach a point at which it doesnt satisfy n>0 and the method will stop calling itself recursivly
to make it look similar you can replace condition if (n == 0 || n == 1) with if (n < 2)
Also i don't see how the line `return fibonacci (n-1) + fibonacci (n-2) would work since fibbonacci n-2 has to contain in some sense fibonacci n-1 in order to wrok but it isn't there yet.
I suspect you wanted to write: "since fibbonacci n-1 has to contain in some sense fibonacci n-2"
If I'm right, then you will see from the example below, that actually fibonacci (n-2) will be called twice for every recursion level (fibonacci(1) in the example):
1. when executing fibonacci (n-2) on the current step
2. when executing fibonacci ((n-1)-1) on the next step
(Also take a closer look at the Spike's comment)
Suppose you call fibonacci(3), then call stack for fibonacci will be like this:
(Veer provided more detailed explanation)
n=3. fibonacci(3)
n=3. fibonacci(2) // call to fibonacci(n-1)
n=2. fibonacci(1) // call to fibonacci(n-1)
n=1. returns 1
n=2. fibonacci(0) // call to fibonacci(n-2)
n=0. returns 1
n=2. add up, returns 2
n=3. fibonacci(1) //call to fibonacci(n-2)
n=1. returns 1
n=3. add up, returns 2 + 1
Note, that adding up in fibonacci(n) takes place only after all functions for smaller args return (i.e. fibonacci(n-1), fibonacci(n-2)... fibonacci(2), fibonacci(1), fibonacci(0))
To see what is going on with call stack for bigger numbers you could run this code.
public static String doIndent( int tabCount ){
String one_tab = new String(" ");
String result = new String("");
for( int i=0; i < tabCount; ++i )
result += one_tab;
return result;
}
public static int fibonacci( int n, int recursion_level )
{
String prefix = doIndent(recursion_level) + "n=" + n + ". ";
if (n == 0 || n == 1){
System.out.println( prefix + "bottommost level, returning 1" );
return 1;
}
else{
System.out.println( prefix + "left fibonacci(" + (n-1) + ")" );
int n_1 = fibonacci( n-1, recursion_level + 1 );
System.out.println( prefix + "right fibonacci(" + (n-2) + ")" );
int n_2 = fibonacci( n-2, recursion_level + 1 );
System.out.println( prefix + "returning " + (n_1 + n_2) );
return n_1 + n_2;
}
}
public static void main( String[] args )
{
fibonacci(5, 0);
}
The trick is that the first call to fibonacci() doesn't return until its calls to fibonacci() have returned.
You end up with call after call to fibonacci() on the stack, none of which return, until you get to the base case of n == 0 || n == 1. At this point the (potentially huge) stack of fibonacci() calls starts to unwind back towards the first call.
Once you get your mind around it, it's kind of beautiful, until your stack overflows.
"How can you use Fibonacci if you haven't gotten done explaining what it is yet?"
This is an interesting way to question recursion. Here's part of an answer: While you're defining Fibonacci, it hasn't been defined yet, but it has been declared. The compiler knows that there is a thing called Fibonacci, and that it will be a function of type int -> int and that it will be defined whenever the program runs.
In fact, this is how all identifiers in C programs work, not just recursive ones. The compiler determines what things have been declared, and then goes through the program pointing uses of those things to where the things actually are (gross oversimplification).
Let me walkthrough the execution considering n=3. Hope it helps.
When n=3 => if condition fails and else executes
return fibonacci (2) + fibonacci (1);
Split the statement:
Find the value of fibonacci(2)
Find the value of fibonacci(1)
// Note that it is not fib(n-2) and it is not going to require fib(n-1) for its execution. It is independent. This applies to step 1 also.
Add both values
return the summed up value
The way it gets executed(Expanding the above four steps):
Find the value of fibonacci(2)
if fails, else executes
fibonacci(1)
if executes
value '1' is returned to step 1.2. and the control goes to step 1.3.
fibonacci(0)
if executes
value '1' is returned to step 1.3. and the control goes to step 1.4.
Add both
sum=1+1=2 //from steps 1.2.2. and 1.3.2.
return sum // value '2' is returned to step 1. and the control goes to step 2
Find the value of fibonacci(1)
if executes
value '1' is returned
Add both values
sum=2+1 //from steps 1.5. and 2.2.
return the summed up value //sum=3
Try to draw an illustration yourself, you will eventually see how it works. Just be clear that when a function call is made, it will fetch its return value first. Simple.
Try debugging and use watches to know the state of the variable
Understanding recursion requires also knowing how the call stack works i.e. how functions call each other.
If the function didn't have the condition to stop if n==0 or n==1, then the function would call itself recursively forever.
It works because eventually, the function is going to petter out and return 1. at that point, the return fibonacci (n-1) + fibonacci (n-2) will also return with a value, and the call stack gets cleaned up really quickly.
I'll explain what your PC is doing when executing that piece of code with an example:
Imagine you're standing in a very big room. In the room next to this room you have massive amounts of paper, pens and tables. Now we're going to calculate fibonacci(3):
We take a table and put it somewhere in the room. On the table we place a paper and we write "n=3" on it. We then ask ourselves "hmm, is 3 equal to 0 or 1?". The answer is no, so we will do "return fibonacci (n-1) + fibonacci (n-2);".
There's a problem however, we have no idea what "fibonacci (n-1)" and "fibonacci (n-2)" actually do. Hence, we take two more tables and place them to the left and right of our original table with a paper on both of them, saying "n=2" and "n=1".
We start with the left table, and wonder "is 2 equal to 0 or 1?". Of course, the answer is no, so we will once again place two tables next to this table, with "n=1" and "n=0" on them.
Still following? This is what the room looks like:
n=1
n=2 n=3 n=1
n=0
We start with the table with "n=1", and hey, 1 is equal to 1, so we can actually return something useful! We write "1" on another paper and go back to the table with "n=2" on it. We place the paper on the table and go to the other table, because we still don't know what we're going to do with that other table.
"n=0" of course returns 1 as well, so we write that on a paper, go back to the n=2 table and put the paper there. At this point, there are two papers on this table with the return values of the tables with "n=1" and "n=0" on them, so we can compute that the result of this method call is actually 2, so we write it on a paper and put it on the table with "n=3" on it.
We then go to the table with "n=1" on it all the way to the right, and we can immediately write 1 on a paper and put it back on the table with "n=3" on it. After that, we finally have enough information to say that fibonacci(3) returns 3.
It's important to know that the code you are writing is nothing more than a recipe. All the compiler does is transform that recipe in another recipe your PC can understand. If the code is completely bogus, like this:
public static int NotUseful()
{
return NotUseful();
}
will simply loop endlessly, or as in my example, you'll keep on placing more and more tables without actually getting anywhere useful. Your compiler doesn't care what fibonacci(n-1) or fibonacci(n-2) actually do.

Categories