Traverse an array recursively - java

I'm trying to make a recursive method that receives an array and traverse it like with a loop, but without a loop.
Couldn't find a way to make an index, and increase each time I call the method.

If you have a function f(array,index) make it do something with array[index] and return function(array,index+1). Finally, to start it off call function(array,0). If there are any variables or state you are building up over the course of the recursive function, also pass it via the arguments.

A shot in the dark, but
public void printMyArray (String[] test, int index) {
// verify the index isn't too large
// Grab a value and do something with it.
}
Edit: As stated above, you basically just need to run through each value in the array. The easiest is really carrying over an index value (in my opinion).

Related

Triple every element of an array with recursion

I've been practicing recursion, trying to get more comfortable with it, but this one problem keeps bugging me.
I'm supposed to write a recursive program that triples each element of an array. At first, it seemed simple enough.
public static void triple (int[] a, int index) {
if (index < a.length()) {
a[index]*=3;
triple(a, index + 1);
}
}
But when I looked at the problem again, I realized that I'd made a mistake. The parameters for the method are only supposed to be an integer array with no index.
How do I go about solving this?
This problem is not the best problem to be solved with recursion.
Leave the method as it is (replace length() with length only).
Overload it with another method:
public static void triple(int[] a) {
triple(a, 0);
}
Then in your code you can go for:
int[] t = {1, 2, 3};
triple(t);
The problem is: this problem can't be really solved using recursion - assuming that you only can pass down the array itself.
The point is: you have to somehow know which indexes have been tripled; and which not.
In other words: you somehow have to cheat; you would have to keep some helper variable somewhere that tells you about the last processed index; or something alike.
But as said; that would mean to implement a solution ... that can only work by "massaging" the requirements.
Meaning: when you really restrict yourself to one method that takes just the array as argument, then you can't solve this puzzle!

Optimizing Java Array Copy

So for my research group I am attempting to convert some old C++ code to Java and am running into an issue where in the C++ code it does the following:
method(array+i, other parameters)
Now I know that Java does not support pointer arithmetic, so I got around this by copying the subarray from array+i to the end of array into a new array, but this causes the code to run horribly slow (I.e. 100x slower than the C++ version). Is there a way to get around this? I saw someone mention a built-in method on here, but is that any faster?
Not only does your code become slower, it also changes the semantic of what is happening: when you make a call in C++, no array copying is done, so any change the method may apply to the array is happening in the original, not in the throw-away copy.
To achieve the same effect in Java change the signature of your function as follows:
void method(array, offset, other parameters)
Now the caller has to pass the position in the array that the method should consider the "virtual zero" of the array. In other words, instead of writing something like
for (int i = 0 ; i != N ; i++)
...
you would have to write
for (int i = offset ; i != offset+N ; i++)
...
This would preserve the C++ semantic of passing an array to a member function.
The C++ function probably relied on processing from the beginning of the array. In Java it should be configured to run from an offset into the array so the array doesn't need to be copied. Copying the array, even with System.arraycopy, would take a significant amount of time.
It could be defined as a Java method with something like this:
void method(<somearraytype> array, int offset, other parameters)
Then the method would start at the offset into the array, and it would be called something like this:
method(array, i, other parameters);
If you wish to pass a sub-array to a method, an alternative to copying the sub-array into a new array would be to pass the entire array with an additional offset parameter that indicates the first relevant index of the array. This would require changes in the implementation of method, but if performance is an issue, that's probably the most efficient way.
The right way to handle this is to refactor the method, to take signature
method(int[] array, int i, other parameters)
so that you pass the whole array (by reference), and then tell the method where to start its processing from. Then you don't need to do any copying.

Using recursion to populate arrays, without implementing method overloading?

Is there a way to use recursion to populate arrays, without implementing method overloading? I want to build a method that takes only an int as argument, and returns an array. The only solution I have thought of is using method overloading; the function that takes int as argument builds the array and passes both the array and the int to the second function, which takes both the int and the array as arguments and implements the actual recursion.
Here is an example:
public static int[] recursiveBuilder(int depth, int[] anArray){
// Base case:
if (depth < 0){
return anArray;
}
// Recursion:
else{
anArray[depth] = depth;
depth--;
return recursiveBuilder(depth, anArray);
}
}
public static int[] recursiveBuilder(int depth){
return recursiveBuilder(depth, new int[depth + 1]);
}
If I declare the array in the recursive part of the overloading, the array would get initialized every time the recursion is called, so I used a second function to declare the array.
Is this approach considered good? Efficient? Is there a way to implement this dynamic in only one method?
Very commonly, a recursive solution requires two methods. The top method is called with the externally meaningful arguments, does any required set-up, and calls the recursive method. The recursive method takes additional arguments.
For example, a recursive binary search may have a top method that that takes as parameters only the probe and a reference to the array. The recursive method also takes a start and end index, so that it can limit itself to a slice of the array.
Java programs usually have a lot of small methods, and Java implementations are designed to handle that. If you can make your code be clear and work with two methods, go with two methods and move on to the next thing.

Calling a method n times: should I use a converted for-each loop or a traditional for loop?

Given the need to loop up to an arbitrary int value, is it better programming practice to convert the value into an array and for-each the array, or just use a traditional for loop?
FYI, I am calculating the number of 5 and 6 results ("hits") in multiple throws of 6-sided dice. My arbitrary int value is the dicePool which represents the number of multiple throws.
As I understand it, there are two options:
Convert the dicePool into an array and for-each the array:
public int calcHits(int dicePool) {
int[] dp = new int[dicePool];
for (Integer a : dp) {
// call throwDice method
}
}
Use a traditional for loop:
public int calcHits(int dicePool) {
for (int i = 0; i < dicePool; i++) {
// call throwDice method
}
}
My view is that option 1 is clumsy code and involves unnecessary creation of an array, even though the for-each loop is more efficient than the traditional for loop in Option 2.
At this point, speed isn't important (insert premature-optimization comment ;). What matters is how quickly you can understand what the code does, which is to call a method dicePool times.
The first method allocates an array of size dicePool and iterates through its values, which happens to run the loop body dicePool times (I'll pretend you meant int instead of Integer to avoid the unrelated autoboxing issue). This is potentially inefficient for the computer running the code, but more importantly it's inefficient for the human reading the code as it's conceptually distant from what you wanted to accomplish. Specifically, you force the reader to think about the new array you've just made, AND the value of the variable a, which will be 0 for every iteration of the loop, even though neither of those are related to your end goal.
Any Java programmer looking at the second method will realize that you're executing the loop body dicePool times with i 'counting up' to dicePool. While the latter part isn't especially important, the beginning is exactly what you meant to do. Using this common Java idiom minimizes the unrelated things a reader needs to think about, so it's the best choice.
When in doubt, go with simplicity. :D
Why would you need to allocate an array to loop over a variable that can be safely incremented and used without any need of allocation?
It sounds unecessarily inefficient. You can need to allocate an array if you need to swap the order of ints but this is not the case. I would go for option 2 for sure.
The foreach is useful when you want to iterate on a collection but creating a collection just to iterate over it when you don't need it is just without sense..
(2) is the obvious choice because there's no point in creating the array, based on your description. If there is, of course things change.
What makes you think that the for-each loop is more efficient?
Iterating over a set is very likely less efficient than a simple loop and counter.
It might help if you gave more context about the problem, specifically whether there's more to this question than choosing one syntax over the other. I am having trouble thinking of a problem to which #1 would be a better solution.
I wouldn't write the first one. It's not necessary to use the latest syntax in every setting.
Your instinct is a good one: if it feels and looks clumsy, it probably is.
Go with #2 and sleep at night.

Recursion Question : Revision

My slides say that:
A recursive call should always be on a smaller data structure than the current one
There must be a non recursive option if the data structure is too small
You need a wrapper method to make the recursive method accessible
Just reading this from the slides makes no sense, especially seeing as it was a topic from before christmas!
Could anyone try and clear up what it means please?
Thank you
A recurssive call should always be on a smaller data structure than the current one
In general this isn't true but if you are talking about linked lists manipulation with recursion it is. What it is implying is that you need to always be working towards a solution and this usually is dealing with a smaller problem than you started with.
Take for example Quicksort. Each time the function is called it is working with a smaller set of data.
Taking another example of printing a linked list, the next time you call the recursive function the argument should be the tail of the linked list (This code has an error in it, but that leads us to our next point)
void printList(List l){
print(l.head);
printList(l.tail);
}
There must be a non recurssive option if the data structure is too small
This means there should be a base case. The point where the function stops calling itself again.
int factorial(int n){
if ( n == 1 ){ //the base case is when n = 1
return 1;
}
return n*factorial(n-1);
}
Going back to the example of printing a linked list, there has to be a case where you only have an empty list left (in which case the function should do nothing). Going back to the code to print a linked list
void printList(List l){
if ( l.empty == true ){ //the base case is when the list l is empty
return;
}
print(l.head);
printList(l.tail);
}
You need a wrapper method to make the recurssive method accessible
I don't know Java, and it isn't really a language designed for recursion, however in many cases your recursive function will have more parameters than the person using the API should be able to see. You might for example want to have a counter in there.
You can have a wrapper function that simplifies the parameters to just what is needed. The wrapper function then calls the real worker function.
An example might be if we have a linked list class that has the recursive function to print the list. Its declaration would look something like this:
void printList(List l);
However as it is a class method, to someone using the API it doesn't make much sence to have to do this:
myList.printList(myList);
So a wrapper function could be created that doesn't have any paramters which then calls the code that does the work.
void printList(){
doPrintList(this); //pass in the List object as the first argument
}
Then all the programmer using the API has to do is:
myList.printList();

Categories

Resources