简体   繁体   中英

Separating even and odd indexes from and ArrayList in Java using recursion

I'm trying to separate even and odd indexes from an ArrayList in java as part of an assignment. It must be a recursive method. Here is what I've tried;;

public ArrayList<Integer> toOddList(ArrayList<Integer> input) {
        ArrayList<Integer> copiedList = (ArrayList<Integer>) input.clone();
        ArrayList<Integer> oddList = new ArrayList<Integer>();
        ArrayList<Integer> evenList = new ArrayList<Integer>();
        int index = (copiedList.size() - 1);      // Sets index to the max size of ArrayList - 1
        if (index <= 0) {
            return oddList;
        }
        if ((index % 2) == 0) {
            evenList.add(copiedList.get(index));  // Adds indexed number to even Arraylist
            copiedList.remove(index);             // Removes index from copiedList
            copiedList = toOddList(copiedList);   // Calls function again
        } else {
            oddList.add(copiedList.get(index));   // Adds indexed number to odd Arraylist
            copiedList.remove(index);             // Removes index from copied List
            copiedList = toOddList(copiedList);   // Call method again
        } return oddList;
    }

If there is any other way to use recursion for this, or to instead use two methods for even and odd separately, any help would be appreciated.

I am borrowing Jarvis' idea of using index rather than cloning the input array. I think the intent here is to make the base case that we have reached the end of the list, and if not we add the current element to the right list, then call ourselves on the rest of the list, taking care to increment the index and switch the spots of the current list and the one that is on deck. Then the method becomes:

//assumes all lists initialized by caller
public void splitList(ArrayList<Integer> input, int index, ArrayList<Integer> current, ArrayList<Integer> onDeck) {
    if (index >= input.size()) { //base case
        return;
    } else { //add the current element and call us on the rest of the list
        current.add(input.get(index));
        splitList(input, index + 1, onDeck, current); //note toggling output list and advancing index
    }
}

and it gets called once the input list is initialized and odds and evens contain freshly constructed empty array lists as follows:

splitList(splitThis, 0, evens, odds);//start with evens because 0 is even

REVISION: I noticed it would be possible not to worry about the index as much and somewhat more natural to make "the rest of the list" a sublist. I also generalized to any kind of list. Thus:

//assumes all lists initialized by caller
public void splitList(List<Integer> input, List<Integer> current, List<Integer> onDeck) {
    if (input.size() == 0) { //base case
        return;
    } else { //add the current element and call us on the rest of the list
        current.add(input.get(0));
        splitList(input.subList(1, input.size()), onDeck, current); //note toggling output list and call on rest of list, if any
    }
}

and the call is simplified to:

splitList(splitThis, evens, odds);//start with evens because 0 is even

Few optimizations we can do in your implementation. U don't even need to create final output list on every recursion call and using java Predicate class we can common out final internal method also.

Please checkout implementation.

  public ArrayList<Integer> buildOddList(ArrayList<Integer> input) {
    ArrayList<Integer> output = new ArrayList<>();
    return buildList(input,0,output,i -> i % 2 != 0 );
  }

  public ArrayList<Integer> buildEvenList(ArrayList<Integer> input) {
    ArrayList<Integer> output = new ArrayList<>();
    return buildList(input,0,output,i -> i % 2 == 0 );
  }

  private ArrayList<Integer> buildList(ArrayList<Integer> input, Integer index, ArrayList<Integer> output, Predicate<Integer> predicate) {

    if (index == input.size()) {
      return output;
    }
    if (predicate.test(index)) {
      output.add(input.get(index));
    }
    return buildList(input,index+1,output,predicate);
  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM