Method Overloading Techinques - java

I have a method overload that goes as follows:
public class Odddetector {
public static void main(String[] args) {
int count = countOdd(new int [] {5, 7, 3, 9, 0});
System.out.println(count);
count = countOdd(new int [] {2, 6, 4, 8, 1});
System.out.println(count);
count = countOdd(5, 7, 10);
System.out.println(count);
count = countOdd(8, 2, 7);
System.out.println(count);
count = countOdd(new int[][] {{1, 2}, {3, 4, 5}});//extra point only
System.out.println(count);
count = countOdd(new int[][] {{6, 2}, {3, 4, 0}});//extra point only
System.out.println(count);
}
public static int countOdd(int[] a){
int count=0;
for (int i: a) count = (i %2 != 0)?++count:count;
return count;
// Do Something;
}
public static int countOdd(int[][] a){
// Do Something;
int count=0;
for (int b = 0; b< a.length; b++){
//System.out.println(java.util.Arrays.toString(a[b])); not a necessary line.
count += countOdd(a[b]);
}
return count;
}
// more method overloading
My question is there a way to condense the solution to have one method that takes into account N-Dimensional Arrays. The code runs fine like this however, I would like to know what Java techniques can help account for the increase in dimensions. I would like to add some details and that is that the first method is the base method, and all the other methods call that first int[] a. The new section I added is the full code I am currently in developing this code which my professor gave as a challenge. I currently have the Data Structures by Lang, and I can accept hints. I prefer hints actually because I would like to learn to code this.

When the parameter is amulti dimensional array, you can recursively call the function that digs down until you end up with a 1d array of numbers. The logic is:
if a is a multi-dimensional array
for each array in a
call recursively
else
count odd numbers in a
I have 2 functions. One that takes a variable number of args, and a recursive one. The first just calls the second with the var args as an array. The varargs function needs a bit of work if you want to allow mixed parameters (eg: countOdd(new int [] {1,2,3}, 4, 5);)
// The var args version. You call this. It then calls the recursive
// version.
public static <T> int countOdd(T... arguments)
{
return countOddRec(arguments);
}
// Recursive version
private static <T> int countOddRec(T[] a)
{
if (a == null || a.length == 0) return 0;
int count=0;
// Is it an array of Numbers?
if (a[0] instanceof Number) {
for (T i: a) {
// Simplified the counting code a bit. Any # mod 2 is either 0 or 1
count += ((Number)i).intValue() % 2;
}
}
// Is it an multi-dimensional? Call recursively for each sub-array.
else {
for (T sub : a) {
count += countOddRec((T[])sub);
}
}
return count;
}
As mentioned in the comments, this will not work for primitive data types (ex: int, etc). Instead, use non-primitive types (ex: Integer, etc).

Well, I guess there are some very interesting problems around, all coupled together. Namely
How to generify array processing and method declaration for
arbitrary depth (this is your initial question)?
How to deep traverse array with unknown depth?
How to inject some useful payload
into array traversal (in your case - count odd numbers)
independently of traversal itself?
Is it possible to generify approach for primitive and object arrays, and how?
I have a good suggestion for points 3: instead of hardcoding payload in the method itself we can produce IntStream (or generic Stream for Object version) which can be processed separately.
On points 1 and 4 my guess it's probably not possible or at least not elegant. java.lang.reflect.Array doesn't show any wonder in this and my assumption is - if JDK couldn't do this, I cannot neither. So, the best option is probably to allow general signature with Object accompanied with couple of frequently used overloads, up to depth 3. Of course, this implies danger of ClassCastExceptions at runtime.
So, final result with implementation of point 2 may look like this
public class FlattenArray {
public static IntStream flatten(int n) {
return IntStream.of(n);
}
public static IntStream flatten(int[] array) {
return IntStream.of(array);
}
public static IntStream flatten(int[][] array) {
return flatten((Object) array);
}
public static IntStream flatten(Object array) {
Class<?> aClass = array.getClass();
if (!aClass.isArray())
return IntStream.of(((Number) array).intValue());
else {
Class<?> componentType = aClass.getComponentType();
if (componentType.isPrimitive())
return IntStream.of((int[]) array);
else
return Arrays.stream((Object[]) array).flatMapToInt(FlattenArray::flatten);
}
}
}
And use this like
long count = FlattenArray.flatten(2, 3, 5, 7).filter(i -> i & 1 != 0).count();

Related

What is the fastest way to fill an ArrayList with null in java?

I want a List of n Sets of Integers and initially this list should be filled with null.
A lot of the Sets will be initialised later, and some will remain null.
I have tried different methods to implement this, some of them are included here:
List<HashSet<Integer>> List_of_Sets = Arrays.asList(new HashSet[n]);
ArrayList<HashSet<Integer>> List_of_Sets = new ArrayList<>(n);
while(n-- > 0) List_of_Sets.add(null);
Is there a faster way to do this?
For clarification an example for arrays would be Arrays.fill() used to be slower than:
/*
* initialize a smaller piece of the array and use the System.arraycopy
* call to fill in the rest of the array in an expanding binary fashion
*/
public static void bytefill(byte[] array, byte value) {
int len = array.length;
if (len > 0){
array[0] = value;
}
//Value of i will be [1, 2, 4, 8, 16, 32, ..., len]
for (int i = 1; i < len; i += i) {
System.arraycopy(array, 0, array, i, ((len - i) < i) ? (len - i) : i);
}
}
^above code is from Ross Drew's answer to Fastest way to set all values of an array?
Is there a faster way to do this?
As far as I am aware, no. Certainly, there is no easy way that is faster.
Based on how it works, I think (but I have not tested) that the Arrays.asList(new HashSet[n]) should be the fastest solution.
It would be possible to implement a custom List implementation that is like an ArrayList but is pre-initialized to N null values. But under the hood the initialization will be pretty much identical with what happens in the List implementation that asList returns. So I doubt that any performance improvements would be significant ... or worth the effort.
If you want to be sure of this, you could write a benchmark of the various options. However, I don't think this is the right approach in this case.
Instead I would recommend benchmarking and profiling your entire application to determine if operations on this list are a real performance hotspot.
If it is not a hotspot, my recommendation would be to just use the Arrays.asList approach and spend your time on something more important.
If it is a hotspot, you should consider replacing the List with an array. From your earlier description it seemed you are going to use the List like an array; i.e. using positional get and set operations, and no operations that change the list size. If that is the case, then using a real array should be more efficient. It saves memory, and avoids a level of indirection and (possibly) some bounds checking.
One reason not to do this would be if you needed to pass the array to some other code that requires a List.
If resizing is not important to you then implementing your own list might be fast. It might also be buggy. It would at least be interesting to benchmark compared to Java's lists. One strange effect that you might see is that standard lists might be optimised by the JIT sooner, as they could be used internally by Java's standard library.
Here is my attempt, although I suggest you don't use it. Use a standard list implementation instead.
import java.util.*;
public class FastListOfNullsDemo {
public static void main(String[] args) {
Set<Integer>[] arr = new Set[100_000]; // all set to null by default.
List<Set<Integer>> myList = new ArrayBackedList<>(arr);
myList.set(3, new TreeSet<Integer>());
myList.get(3).add(5);
myList.get(3).add(4);
myList.get(3).add(3);
myList.get(3).add(2);
myList.get(3).add(1);
// Let's just print some because 100,000 is a lot!
for (int i = 0; i < 10; i++) {
System.out.println(myList.get(i));
}
}
}
class ArrayBackedList<T> extends AbstractList<T> {
private final T[] arr;
ArrayBackedList(T[] arr) {
this.arr = arr;
}
#Override
public T get(int index) {
return arr[index];
}
#Override
public int size() {
return arr.length;
}
#Override
public T set(int index, T value) {
T result = arr[index];
arr[index] = value;
return result;
}
}
Another possibility would be implementing an always-null, fixed-size list. Use that to initialise the ArrayList. I won't promise that it is fast but you could try it out.
import java.util.*;
public class FastListOfNullsDemo {
public static void main(String[] args) {
List<Set<Integer>> allNull = new NullList<>(100_000);
List<Set<Integer>> myList = new ArrayList<>(allNull);
myList.set(3, new TreeSet<Integer>());
myList.get(3).add(5);
myList.get(3).add(4);
myList.get(3).add(3);
myList.get(3).add(2);
myList.get(3).add(1);
System.out.println(myList.size());
// Let's just print some because 100,000 is a lot!
for (int i = 0; i < 10; i++) {
System.out.println(myList.get(i));
}
}
}
class NullList<T> extends AbstractList<T> {
private int count;
NullList(int count) {
this.count = count;
}
#Override
public T get(int index) {
return null;
}
#Override
public int size() {
return count;
}
}

how to find duplicate value from array without using loop

Can anyone help me to provide the code for finding duplicate values from the array. Here the condition is no loop statements. I tried with recursion method but it not working out. Pls anyone help me on this.
My attempt:
public static void main(String[] args) {
Integer a[] = { 1, 2, 7, 3, 4, 5, 2, 7 };
ArrayList<Integer> al = new ArrayList<Integer>(Arrays.asList(a));
if (duplicate(al) == true) {
System.out.println("Duplicate");
}
}
static int i = 1;
private static boolean duplicate(ArrayList<Integer> al) {
if (al.get(i) != null) {
if (al.get(i - 1) == al.get(i)) {
System.out.println("Duplicate are : " + al.get(i));
}
} else {
return true;
}
i++;
return duplicate(al);
}
Please refer below code to find duplicates in array without loop
public class ArrayDuplicate {
public static void main(String[] args) {
findDuplicateElementsInArray(new int[] { 20, 10, 20, 5, 10 });
}
private static void findDuplicateElementsInArray(int arr[]) {
Set<Integer> uniqueElements = new LinkedHashSet<Integer>();
Arrays.stream(arr).filter(i -> !uniqueElements.add(i)).forEach(System.out::println);
}
}
This isn't a good use case for recursion, which leads me to wonder what the point of the problem is. However, it's worth noting that LISP programmers (from what I've observed) traditionally used recursion for everything; early versions of the language may not have had any kind of loop construct. When programming in this way, one gets used to figuring out how to use recursion for an algorithm that would be a loop in any other language.
The main technique, I think, is to figure out what running local variables you'll need to keep, and pass them as parameters to a recursive helper function.
To solve this problem with a loop, I'd define a Set that is initially empty. As I go through the array, I'd: (1) see if the array element is already in the set, and return true if it is; (2) add the element to the set.
Here, the Set is the running variable that you need to keep. The array index is another "running variable". (In classic LISP, you'd just use a cdr function that means "the rest of the list", so you wouldn't need to maintain an index; I don't think that's easy to do with a Java ArrayList.) So you'll want a recursive method that has a Set and a "current index" as a parameter:
private boolean hasDuplicateHelper(ArrayList<Integer> a, int currentIndex, Set<Integer> alreadySeen) { ... }
The outer method will initialize the set to an empty set and call the helper with it this set, and with 0 as the current index. The recursive method will (1) look at the current element and see if it's in alreadySeen and return true if it is; (2) add the current element to the set; (3) call the method recursively with the new set as the alreadySeen parameter, and with the appropriate new value for the current index (I'll let you figure that one out).
I'll leave it to you to work out the rest of the details, such as how to stop.
EDIT: Now that it's clear from the comments that the desired result is to print the duplicate values instead of just "yes" or "no", something will have to change. But I think this can be done just by changing the method result to a Set<Integer> that contains a set of all the duplicates. If more information is needed, such as the indexes where the duplicates occur or the number of times each duplicate occurs, a different result structure may have to be used.
I completed the code to find the duplicate number from the array without using the loop statement. I implemented two recursions to finalize the code. Please check code on below
static int size;
public static void main(String[] args) {
Integer a[] = { 2, 10, 6, 1, 2, 4, 6, 10, 1 };
ArrayList<Integer> al = new ArrayList<Integer>(Arrays.asList(a));
size = a.length - 1;
findDuplOne(al, 0);
}
static int i = 0;
private static void findDuplOne(ArrayList<Integer> al, int i) {
if (i <= size) {
int valOne = al.get(i);
i++;
findDuplTwo(al, i, valOne);
findDuplOne(al, i);
}
}
private static void findDuplTwo(ArrayList<Integer> al, int i, int compareVal) {
if (i <= size) {
int valOne = al.get(i);
if (compareVal == valOne) {
System.out.println("Duplicate is " + compareVal);
}
i++;
findDuplTwo(al, i, compareVal);
}
}
Simply you can try it. If you pass your array object then it will return the count of duplicates.
public static int findDuplicatesCountOnArray(Integer[] arr) {
List<Integer> list = new ArrayList<Integer>();
if (arr != null) {
list.addAll(Arrays.asList(arr));
}
HashSet<Integer> set = new HashSet<Integer>(list);
return list.size() - set.size();
}

How to return a specific element of an array?

I want to return odd numbers of an array yet Eclipse doesn't seem to accept my return array[i]; code. I think it requires returning a whole array since I set an array as a parameter to my method.
As I said before, I need to pass an array and get a specific element of that array in return. Even if I make that array static, how do I return a single element?
Edit : Alright then, here it is:
public class newClass{
public static void main(String[] args)
{
int [] newArray= new int [4];
int [] array = {4,5,6,7};
newArray[0] = array[0]+array[1]+array[2]+array[3];
newArray[1] = array[0]*array[1]*array[2]*array[3];
newArray[2] = findOut(array);
}
public static int findOut (int [] array3)
{
int e1=0;
int e2=0;
for (int i=0; i<array3.length; i++)
{
if (array3[i]%2==0)
{
e1+=array3[i];
array3[i]=e1
return array3[i];
}
else
{
e2+=array3[i];
array3[i]=e2;
return array3[i];
}
}
}
}
I know there are probably more than a few mistakes here but I'm working on it and I'm not only returning odd numbers, I also add them together.
You code should look like this:
public int getElement(int[] arrayOfInts, int index) {
return arrayOfInts[index];
}
Main points here are method return type, it should match with array elements type and if you are working from main() - this method must be static also.
I want to return odd numbers of an array
If i read that correctly, you want something like this?
List<Integer> getOddNumbers(int[] integers) {
List<Integer> oddNumbers = new ArrayList<Integer>();
for (int i : integers)
if (i % 2 != 0)
oddNumbers.add(i);
return oddNumbers;
}
Make sure return type of you method is same what you want to return.
Eg:
`
public int get(int[] r)
{
return r[0];
}
`
Note : return type is int, not int[], so it is able to return int.
In general, prototype can be
public Type get(Type[] array, int index)
{
return array[index];
}
(Edited.) There are two reasons why it doesn't compile: You're missing a semi-colon at the end of this statement:
array3[i]=e1
Also the findOut method doesn't return any value if the array length is 0. Adding a return 0; at the end of the method will make it compile. I've no idea if that will make it do what you want though, as I've no idea what you want it to do.

Returning multiple values from a recursive function

I have this problem where I have to convert a decimal number to binary and then store the bits in a linked list where the head node is the most significant bit and the last node is the least significant bit. Solving the problem itself is actually easy as you only need to keep taking the modulo of 2 recursively and add the result in the list until the decimal number becomes 0.
Where I'm stuck is that I have to write the function such that it returns a pair of number, (whether an array or a list) of the most significant bit and the last significant bit.
i.e: Inputting 14 in the function would return (1, 0), since 14 is 1110 in binary.
I do have access to the MSB and LSB easily(getFirst(), getLast()).
The function can only take one argument which is the decimal number.
Currently I have this current code:
public static void encodeBin(int n) {
if(n == 0) return; //Base case
else {
if(n % 2 == 0)
theList.addFirst(0);
else
theList.addFirst(1);
encodeBin(n / 2);
}
// return?
}
The problem is I can't figure out how return the 2 values. Haveing a return value means I can't call encodeBin() by itself.
Moreover, where should I create the list? If I put something like List<Integer> = new LinkedList<Integer>() at the very beginning of the function, then each time the function calls itself, it creates a new list and adds the bits in THAT new list not the original right?(The list created from when the function is called the first time)
Anybody knows how to solve this?
You cannot return 2 values. You are going to have to return some object that contains the 2 values. either an array or some new object, depending on your homework requirments and where this function is going to be used.
For the linkedlist creation, what you need is a recursive helper method. Your public method will be used to initialize your objects, start the recursion, and return your result. This allows your actual recursive function to have more than 1 argument.
public static SOME_TYPE encodeBin(int n) {
LinkedList result = new LinkedList();
encodeBin_helper(result,n);
// return the MSB and LSB
}
public static void encodeBin_helper(LinkedList theList, int n) {
if(n == 0) return; //Base case
else {
if(n % 2 == 0)
theList.addFirst(0);
else
theList.addFirst(1);
encodeBin_helper(theList, n/2);
}
}
You can't return two values separately. You can, however, return an array containing the first bit and the last bit or create your own class to hold this data, and return an instance of that class.
And about the list, I see two options:
Make it a static class variable
Make it an argument of the function (although I see you said you couldn't do this).
The first method would look like this:
public class MyClass {
private static List<Integer> theList = new LinkedList<Integer>();
// `encodeBin` method as you have it
}
The second method would look like this:
public static void encodeBin(int n, List<Integer> theList) {
if(n == 0) return; //Base case
else {
if(n % 2 == 0)
theList.addFirst(0);
else
theList.addFirst(1);
encodeBin(n / 2, theList);
}
}
You could then do something along the lines of
List<Integer> theList = new LinkedList<Integer>();
encodeBin(14, theList);
and theList would hold the appropriate bits as desired.
As a note, you might want to consider making this a list of booleans instead of integers, with true representing 1 and false representing 0.
I suggest declaring two methods:
(1) public static int[] encodeBin(int n)
and
(2) private static void encodeBin(LinkedList, int n)
The public method merely creates an empty list and then calls the private version passing both the empty list and the orignal input n as the parameters
something like this:
public static int[] encodeBin(int n) {
LinkedList<Integer> aList = new LinkedList<Integer>();
encodeBin(aList , n);
int MSB = aList.getFirst();
int LSB = aList.getLast();
return new int[] {MSB, LSB};
}
private static void encodeBin(LinkedList<Integer> list, n) {
//your recursive version here
}

Refactor this recursive method?

I'm pretty new to the idea of recursion and this is actually my first attempt at writing a recursive method.
I tried to implement a recursive function Max that passes an array, along with a variable that holds the array's size in order to print the largest element.
It works, but it just doesn't feel right!
I have also noticed that I seem to use the static modifier much more than my classmates in general...
Can anybody please provide any general tips as well as feedback as to how I can improve my code?
public class RecursiveTry{
static int[] n = new int[] {1,2,4,3,3,32,100};
static int current = 0;
static int maxValue = 0;
static int SIZE = n.length;
public static void main(String[] args){
System.out.println(Max(n, SIZE));
}
public static int Max(int[] n, int SIZE) {
if(current <= SIZE - 1){
if (maxValue <= n[current]) {
maxValue = n[current];
current++;
Max(n, SIZE);
}
else {
current++;
Max(n, SIZE);
}
}
return maxValue;
}
}
Your use of static variables for holding state outside the function will be a source of difficulty.
An example of a recursive implementation of a max() function in pseudocode might be:
function Max(data, size) {
assert(size > 0)
if (size == 1) {
return data[0]
}
maxtail = Max(data[1..size], size-1)
if (data[0] > maxtail) {
return data[0]
} else {
return maxtail
}
}
The key here is the recursive call to Max(), where you pass everything except the first element, and one less than the size. The general idea is this function says "the maximum value in this data is either the first element, or the maximum of the values in the rest of the array, whichever is larger".
This implementation requires no static data outside the function definition.
One of the hallmarks of recursive implementations is a so-called "termination condition" which prevents the recursion from going on forever (or, until you get a stack overflow). In the above case, the test for size == 1 is the termination condition.
Making your function dependent on static variables is not a good idea. Here is possible implementation of recursive Max function:
int Max(int[] array, int currentPos, int maxValue) {
// Ouch!
if (currentPos < 0) {
raise some error
}
// We reached the end of the array, return latest maxValue
if (currentPos >= array.length) {
return maxValue;
}
// Is current value greater then latest maxValue ?
int currentValue = array[currentPos];
if (currentValue > maxValue) {
// currentValue is a new maxValue
return Max(array, currentPos + 1, currentValue);
} else {
// maxValue is still a max value
return Max(array, currentPos + 1, maxValue);
}
}
...
int[] array = new int[] {...};
int currentPos = 0;
int maxValue = array[currentPos] or minimum int value;
maxValue = Max(array, currentPos, maxValue);
A "max" function is the wrong type of thing to write a recursive function for -- and the fact you're using static values for "current" and "maxValue" makes your function not really a recursive function.
Why not do something a little more amenable to a recursive algorithm, like factorial?
"not-homework"?
Anyway. First things first. The
static int[] n = new int[] {1,2,4,3,3,32,100};
static int SIZE = n.length;
have nothing to do with the parameters of Max() with which they share their names. Move these over to main and lose the "static" specifiers. They are used only once, when calling the first instance of Max() from inside main(). Their scope shouldn't extend beyond main().
There is no reason for all invocations of Max() to share a single "current" index. "current" should be local to Max(). But then how would successive recurrences of Max() know what value of "current" to use? (Hint: Max() is already passing other Max()'s lower down the line some data. Add "current" to this data.)
The same thing goes for maxValue, though the situation here is a bit more complex. Not only do you need to pass a current "maxValue" down the line, but when the recursion finishes, you have to pass it back up all the way to the first Max() function, which will return it to main(). You may need to look at some other examples of recursion and spend some time with this one.
Finally, Max() itself is static. Once you've eliminated the need to refer to external data (the static variables) however; it doesn't really matter. It just means that you can call Max() without having to instantiate an object.
As others have observed, there is no need for recursion to implement a Max function, but it can be instructive to use a familiar algorithm to experiment with a new concept. So, here is the simplified code, with an explanation below:
public class RecursiveTry
{
public static void main(String[] args)
{
System.out.println(Max(new int[] {1,2,4,3,3,32,100}, 0, 0));
}
public static int Max(int[] n, int current, int maxValue)
{
if(current < n.Length)
{
if (maxValue <= n[current] || current == 0))
{
return Max(n, current+1, n[current]);
}
return Max(n, current+1, maxValue);
}
return maxValue;
}
}
all of the static state is gone as unnecessary; instead everything is passed on the stack. the internal logic of the Max function is streamlined, and we recurse in two different ways just for fun
Here's a Java version for you.
public class Recursion {
public static void main(String[] args) {
int[] data = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
System.out.println("Max: " + max(0, data));
}
public static int max(int i, int[] arr) {
if(i == arr.length-1) {
return arr[i];
}
int memo = max(i+1, arr);
if(arr[i] > memo) {
return arr[i];
}
return memo;
}
}
The recurrence relation is that the maximum element of an array is either the first element, or the maximum of the rest of the array. The stop condition is reached when you reach the end of the array. Note the use of memoization to reduce the recursive calls (roughly) in half.
You are essentially writing an iterative version but using tail recursion for the looping. Also, by making so many variables static, you are essentially using global variables instead of objects. Here is an attempt at something closer to a typical recursive implementation. Of course, in real life if you were using a language like Java that doesn't optimize tail calls, you would implement a "Max" function using a loop.
public class RecursiveTry{
static int[] n;
public static void main(String[] args){
RecursiveTry t = new RecursiveTry(new int[] {1,2,4,3,3,32,100});
System.out.println(t.Max());
}
RecursiveTry(int[] arg) {
n = arg;
}
public int Max() {
return MaxHelper(0);
}
private int MaxHelper(int index) {
if(index == n.length-1) {
return n[index];
} else {
int maxrest = MaxHelper(index+1);
int current = n[index];
if(current > maxrest)
return current;
else
return maxrest;
}
}
}
In Scheme this can be written very concisely:
(define (max l)
(if (= (length l) 1)
(first l)
(local ([define maxRest (max (rest l))])
(if (> (first l) maxRest)
(first l)
maxRest))))
Granted, this uses linked lists and not arrays, which is why I didn't pass it a size element, but I feel this distills the problem to its essence. This is the pseudocode definition:
define max of a list as:
if the list has one element, return that element
otherwise, the max of the list will be the max between the first element and the max of the rest of the list
A nicer way of getting the max value of an array recursively would be to implement quicksort (which is a nice, recursive sorting algorithm), and then just return the first value.
Here is some Java code for quicksort.
Smallest codesize I could get:
public class RecursiveTry {
public static void main(String[] args) {
int[] x = new int[] {1,2,4,3,3,32,100};
System.out.println(Max(x, 0));
}
public static int Max(int[] arr, int currPos) {
if (arr.length == 0) return -1;
if (currPos == arr.length) return arr[0];
int len = Max (arr, currPos + 1);
if (len < arr[currPos]) return arr[currPos];
return len;
}
}
A few things:
1/ If the array is zero-size, it returns a max of -1 (you could have another marker value, say, -MAX_INT, or throw an exception). I've made the assumption for code clarity here to assume all values are zero or more. Otherwise I would have peppered the code with all sorts of unnecessary stuff (in regards to answering the question).
2/ Most recursions are 'cleaner' in my opinion if the terminating case is no-data rather than last-data, hence I return a value guaranteed to be less than or equal to the max when we've finished the array. Others may differ in their opinion but it wouldn't be the first or last time that they've been wrong :-).
3/ The recursive call just gets the max of the rest of the list and compares it to the current element, returning the maximum of the two.
4/ The 'ideal' solution would have been to pass a modified array on each recursive call so that you're only comparing the first element with the rest of the list, removing the need for currPos. But that would have been inefficient and would have bought down the wrath of SO.
5/ This may not necessarily be the best solution. It may be that by gray matter has been compromised from too much use of LISP with its CAR, CDR and those interminable parentheses.
First, let's take care of the static scope issue ... Your class is defining an object, but never actually instantiating one. Since main is statically scoped, the first thing to do is get an object, then execute it's methods like this:
public class RecursiveTry{
private int[] n = {1,2,4,3,3,32,100};
public static void main(String[] args){
RecursiveTry maxObject = new RecursiveTry();
System.out.println(maxObject.Max(maxObject.n, 0));
}
public int Max(int[] n, int start) {
if(start == n.length - 1) {
return n[start];
} else {
int maxRest = Max(n, start + 1);
if(n[start] > maxRest) {
return n[start];
}
return maxRest;
}
}
}
So now we have a RecursiveTry object named maxObject that does not require the static scope. I'm not sure that finding a maximum is effective using recursion as the number of iterations in the traditional looping method is roughly equivalent, but the amount of stack used is larger using recursion. But for this example, I'd pare it down a lot.
One of the advantages of recursion is that your state doesn't generally need to be persisted during the repeated tests like it does in iteration. Here, I've conceded to the use of a variable to hold the starting point, because it's less CPU intensive that passing a new int[] that contains all the items except for the first one.

Categories

Resources