Java Homework Help - Recursion with array - java

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.

Related

How do I count up using recursion in 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.

Why is there a "0" value remaining in the list, despite code that removes "0" values?

I am working through sample questions for the Computer Science A exam and cannot figure out why the correct answer is correct on the following problem.
Consider the following method.
public static void mystery(List<Integer> nums)
{
for (int k = 0; k < nums.size(); k++)
{
if (nums.get(k).intValue() == 0)
{
nums.remove(k);
}
}
}
Assume that a List values initially contains the following Integer values.
[0, 0, 4, 2, 5, 0, 3, 0]
What will values contain as a result of executing mystery(values)?
The correct answer showing is : [0, 4, 2, 5, 3]
Why does the first 0 remain in the list?
The first 0 remains because that was really the second 0 in nums.
When k is 0, the test succeeds and remove(0) is called, removing the first index. That shifts all the other elements down, so that the list is now [0, 4, 2, 5, 0, 3, 0]. But then k is incremented to 1, so the second 0 (now at index 0) is skipped and not removed.
The other 0 values are removed successfully, just as the first 0 is removed successfully. This code skips only the second of two consecutive 0 values. This would be a bug, assuming that the code is supposed to remove all 0 values.
The answer already given by #rgettman is correct. However, I'd like to add that this is a particular example of a common issue - that of modifying a sequence (collection, whatever) while iterating (indexing, whatever) through it. You need to understand the effect that the modification will have on the in-progress iteration. And sometimes the effect is formally given as "undefined", i.e., you don't want to do it.
For Java, the Iterator<> class has a remove() method that safely removes the current element. If you actually wanted to remove all zeroes from your List<>, rather than just explaining what is happening in the test question, then Iterator would be one way to go about it.

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.

Recursively merge two arrays, taking alternate elements (Java)

I really need help with a homework problem. I've been trying to figure this out for days and would really appreciate some assistance! Here's the prompt:
Merge two arrays into one. Write a method named merge which takes 3 interger array
parameters: a, b, and soln. soln is guaranteed to be the size of a.length + b.length. The arrays a and b should be "merged" into one array by alternating elements. Add a 4th parameter, which indicates which element in soln should be updated for a given recursive call of the method.
Examples:
merge({1, 2, 3}, {4, 5, 6}, soln, 0) should end with the following values in soln: {1, 4, 2, 5, 3, 6}
merge({1,2}, {3,4,5}, soln, 0) should end with the following values in soln: {1,3,2,4,5}
I can get it to work with the arrays are the same length, and even when the arrays differ in length (but only by one element). I can't get the index to line up correctly. I've tried many different variations, but here's what I have so far:
public static void merge3(int[] a, int[] b, int[] soln, int index) {
if (index > soln.length-1) {
return; //if index reaches end of soln length
}
int index2 = (int)(index/2); //allows me to pull alternately from a and b arrays. As index goes up, index2 becomes 0, 0, 1, 1, 2, 2, etc.
if (b.length >= a.length) {
if (index%2 == 0) {
if (index2 > a.length-1) {
soln[index] = b[index2];
merge3(a, b, soln, index+1);
} else {
soln[index] = a[index2];
merge3(a, b, soln, index+1);
}
} else {
soln[index] = b[index2];
merge3(a, b, soln, index+1);
}
} else if (b.length < a.length) {
if (index%2 == 0) {
soln[index] = a[index2];
merge3(a, b, soln, index+1);
} else {
if (index2 >= b.length) {
soln[index] = a[index2];
merge3(a, b, soln, index+1);
} else {
soln[index] = b[index2];
merge3(a, b, soln, index+1);
}
}
}
}
If array a is {1, 2, 3} and array b is {4, 5, 6, 7, 8, 9}, soln becomes {1, 4, 2, 5, 3, 6, 7, 7, 8} instead of what it's supposed to be, which is {1, 4, 2, 5, 3, 6, 7, 8, 9}. It's off because when I do index + 1, the recursive call catches on the same value (index2) which was used to alternate between the arrays when there's only one array left. Please help! Thank you!
Here is an intentionally pedantic approach to thinking through this kind of problem.Start by determining your state. One way to divide all the possibilities in this problem into distinct states is:
exit, where you will simply return. (always need this for every recursively called method).
before array exhaustion, where you still have at least one array element left in each of the input arrays a and b.
after array exhaustion, where all of the smaller array's elements have already been added to soln
array a empty where the first array has no elements. Normally you would handle this outside a recursive call, but we're following rules here...
Each of these states represents a different way that you need to handle your inputs.
The pseudocode for this type of structure would look like:
if (test to see if we're in "exit" state) {
logic handling "exit" state
} else {
if (test to see if we're in "before array exhaustion" state) {
logic handling "before array exhaustion" state
} else {
if (test to see if we're in "array `a` empty" state ) {
logic handling "array `a` empty" state
} else {
logic handling "after array exhaustion" state
}
}
}
recursive call to your method here
You already have the (test to see if we're in "exit" state) here:
if (index > soln.length-1) {
and you have the logic handling "exit" state here:
return; //if index reaches end of soln length
Since this state's logic returns, the syntax doesn't require that you put it in an if-else like it is in the pseudocode, but it might be clearer while you're getting a handle on Java syntax if you consistently use the if-else structure throughout.
After that you need your if (test to see if we're in "before array exhaustion" state), conditional, but instead your code assumes you're at logic handling "before array exhaustion" state and handles it accordingly. The logic is good, but the state isn't. You'll need to use the template and put that logic in its proper place, but at least you don't have to rewrite it.
Now fill out the rest of the pseudocode template, starting with the tests.
Tests:
The test to see if we're in "array 'a' empty" state just looks to see if array a is empty or not, so it's pretty trivial to write.
The test to see if we're in "before array exhaustion" state checks whether we've already copied all of the smaller array's elements into soln yet or not, based on a.length, b.length, and index.
Array population logic:
What you've got below your exit case works perfectly for logic handling "before array exhaustion" state, so you just need to write:
logic handling "array 'a' empty" state where you already know array a is empty.
logic handling "after array exhaustion" state. This is the part where we're all done with the smaller array, and we need to know which element to pull from the larger input array so that we can add it to soln.
So basically follow the template and write the 3 tests (1 already done, one trivial, and one more), and then write the logic for the different states (two already done, one trivial, and one more) and you're there.
You might also consider refactoring your existing code so that there's only one recursive call that happens at the very end. That's called tail recursion, and even with all the optimizations that Java SE 8 has, it's still better this way. It's also a lot cleaner.
Hopefully this is a useful template for thinking through a simple problem.

Check whether list of number is sequential or not

I have quite a layman question about Java programming.
I would like to write a function to check whether a list of number is sequential or not.
Say [1, 2, 3, 4, 5], the function will return true,
but for [1, 3, 4, 9, 10], the function will return false.
Could anyone help me?
Thank so much!
Write a loop that looks at each element of the list.
For each position i in the list, test that listi + 1 equals listi + 1.
You can code it yourself as an exercise. (Don't forget to deal with the edge cases ...)
UPDATE: ... for people treating this problem as a learning exercise.
A simple direct implementation approach is probably the best idea; e.g. #Joe's final answer. However, the simple approach doesn't always work well ... or at all:
Some Java List implementations have a get method that is O(N). That would lead to an O(N^2) algorithm overall.
Sometimes a a list can only be accessed using an iterator; i.e. list.get(i) might not be an option.
In such cases, you could implement the algorithm with one pass through the list using an iterator. You need to keep "the previous element" in variable, etcetera.
Logic is simple. Just get the first number and check whether it matches with the next value. Like that check adjacent values. Break if the condition fails at any point. The list will be sequential if all the if condition is true.
As Stephen C said, it is a very simple logic
int a[] = { 1, 2, 3, 4, 5,7 };
boolean flag = true;
for (int i = 0; i < a.length - 1; i++) {
if (a[i + 1] != a[i] + 1) {
flag = false;
break;
}
}
System.out.println("Flag is " + flag);

Categories