2

solving something in algoexpert and getting weird index out of bound exception:

the question is simply to take an array and another int and put all the numbers that equal to this int in the end of the array, like this:

array: [2, 1, 2, 2, 2, 3, 4, 2] integer toMove: 2

output: [1,3,4,2,2,2,2,2]

so I wrote this algorithm:

class Program {
  public static List<Integer> moveElementToEnd(List<Integer> array, int toMove) {
    // Write your code here.
        int newArr[] = new int[array.size()];
        int lastIndertedNotToMoveIdx = 0;
        int endOfArrayIdx = array.size();
        // ArrayList<Integer> list = new ArrayList<Integer>();
        for (int i = 0; i <= array.size(); i++) {
            if (array.get(i) == toMove) {
                newArr[endOfArrayIdx] = array.get(i);
                    endOfArrayIdx = endOfArrayIdx-1;
            } else {
                newArr[lastIndertedNotToMoveIdx] = array.get(i);
                lastIndertedNotToMoveIdx++;
            }
        }
                
      List<Integer> ret_list = new ArrayList<Integer>();
      for(Integer num:newArr) {
         ret_list.add(num);
      }
    return ret_list;
  }
}

but here newArr[endOfArrayIdx] = array.get(i); I get this message:

java.lang.ArrayIndexOutOfBoundsException: Index 8 out of bounds for length 8
    at Program.moveElementToEnd(Program.java:12)
    at AeJsonTest.getActual(AeJsonTest.java:27)
    at Main.main(Main.java:57)

not sure why...

4
  • 1
    that message on it's own is only a part of a stacktrace without the relevant part. IndexOutOfBounds means you are using an index that is to big, remember, indices are 0 based Commented Jun 1, 2021 at 8:02
  • 1
    @Stultuske: the message was in the post, but hidden due to a formatting error, I've made it visible now. Commented Jun 1, 2021 at 8:46
  • 1
    In Lists/arrays only index 0 .. size-1 are possible. So endOfArrayIdx should be array.size()-1. Commented Jun 1, 2021 at 9:06
  • (There are more lessons to take here: 1) distil something problematic to the most simple form showing the same (mis)behaviour. 2) Stick to the problem statement like glue: when the task is to take an array, implementing a function taking a List<> parameter looks a detour.) Commented Jun 1, 2021 at 12:26

3 Answers 3

1

endOfArrayIdx should start at array.size() - 1, rather than array.size(), which is the array's length. The array's length is always an invalid index for the array.

Also, the for loop condition should be i < array.size(), not i <= array.size().

Sign up to request clarification or add additional context in comments.

Comments

0
newArr[endOfArrayIdx] = array.get(i);

should be:

newArr[endOfArrayIdx - 1] = array.get(i);

as arrays in java go from 0 to length - 1.

Comments

0

Since you have a list, use it! It'll be much easier than what you do. And your risk of "weird IndexOutOfBoundException" will be reduced.

  static List<Integer> moveElementToEnd(List<Integer> array, int toMove) {
    for (int i = 0, lastElementIndex = array.size() - 1; i <= lastElementIndex; ) {
      if (array.get(i) == toMove) {
        array.remove(i);
        array.add(toMove);
        lastElementIndex--;
      } else {
        i++;
      }
    }
    return array;
  }

An alternative would be to not touch the input list at all. Here you don't even have any index!

  static List<Integer> moveElementToEnd(List<Integer> array, int toMove) {
    List<Integer> head = new ArrayList<>();
    int toMoveCount = 0;
    for (int value : array) {
      if (value == toMove) {
        toMoveCount++;
      } else {
        head.add(value);
      }
    }
    head.addAll(Collections.nCopies(toMoveCount, toMove));
    return head;
  }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.