1

Im trying to find the mode of an int array. I have come up with an algorithm that i feel should work, but it isn't. I get the following error:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1
at Statistik.typvärde(Statistik.java:157)
at Statistik.main(Statistik.java:17)

Here is my code:

public static int typvärde(int list[]) {
  int oc[] = new int[list.length];
  int counter = 0;
  int typvärde = 0;
  int max = 0;
  int typindex = 0;

  for(int i = 0; i < list.length; i++) {
     for(int j = 0; j < list.length; j++) {
        if(list[i] == list[j]) {
           counter++;
        }
        oc[i] = counter;  
     }         
  }
  max = Maxmin.max(oc);//class function that finds max of an array
  typindex = Arrays.asList(oc).indexOf(max);
  typvärde = list[typindex];


  return typvärde;  
}
1
  • This code seems to work. But why are you calling max? Since you know that max in your code is lenght of array. You are passing counter which is increased every time... Commented Oct 25, 2015 at 23:23

1 Answer 1

5

Arrays.asList(oc) will create a List<int[]> that contains a single array element, not a List<Integer>.

So indexOf will always return -1 since you call it with an integer (the only case you will get 0 is when you call indexOf(oc) since arrays don't override equals nor hashcode).

Either write your own indexOf method that search into a primitive array or use an array of references (Integer[]).

When you fixed that, you still need to check the return value before accessing list[typindex].


This was for the subtile bug in your code. Now as said in comments, you have a logical error. You need to reset the counter at each iteration of the outer loop, otherwise counter will keep being increased and Maxmin.max(oc) will always returns the last element of the array.

That said, you might want to use another approaches. Here's some ideas:

  • sort the array first and then iterate one time through it having variables that associates the number of times the number you're reading appear. When the number changes, just compare what was the occurence of the last one you read and update the variables accordingly.

So for example, if you have the array {1,7,2,3,3,7,2,7}, you sort it first so that you get {1,2,2,3,3,7,7,7}. Then you read the 1. When you finished to read the 2's you check if the number of times you read them was more than the 1's. If yes you update the variables and you keep reading the next datas until the end.

  • use a Map<Integer, Integer> that maps a number with its number of occurrences in the array. Then just return the entry's key that has the highest associated value.
Sign up to request clarification or add additional context in comments.

5 Comments

Good catch with the int[]
This answer is partly right, but you've missed another important issue with the code - the fact that counter is not reset in each iteration of the outer loop. The result of this is that the largest value of oc[i] is always the last value, regardless of what values are actually in the input.
@DavidWallace Yes, I only focused on the subtile error the code has and didn't read what it was actually doing. I've edited the answer.
Much better now. I have replaced my downvote with an upvote.
... and the second approach could be a one-liner using Java 8 (with the method returning an Optional<Integer>): return IntStream.of(list == null ? new int[]{} : list).boxed().collect(groupingBy(identity(), counting())).entrySet().stream().max(Map.Entry.comparingByValue()).map(Map.Entry::getKey);

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.