0

I am trying to write a java method to find the mode in an unsorted integer array. This works fine when there is only one mode within the array. But it gives out a random number when there's no mode in the array.

And also I need to make sure that my method addresses multimodal arrays as well. But I find difficulty in editing the code to return an array of modes.

public static int mode(int[] marksArray){

    int maxValue =0;int maxCount = 0;

    for (int i = 0; i < marksArray.length; ++i) {
        int count = 0;
        for (int j = 0; j < marksArray.length; ++j) {
            if (marksArray[j] == marksArray[i]) ++count;
        }
        if (count > maxCount) {
            maxCount = count;
            maxValue = marksArray[i];
        }
    }
    return maxValue;
}

2 Answers 2

2

If there's more than one mode in the array then your code returns the first, which is not unreasonable.

To return all modes you need to maintain a list.

static List<Integer> mode(int[] array)
{
    List<Integer> mode = new ArrayList<>();

    int maxCount = 2;
    for(int i=0; i<array.length; i++)
    {               
        int count = 1;
        for(int j=i+1; j<array.length; j++)
            if(array[i] == array[j]) count++;

        if(count >= maxCount)
        {
            if(count > maxCount)
            {
                mode.clear();
                maxCount = count;
            }
            mode.add(array[i]);
        }
    }

    return mode;            
}

Note that there's no need to start the inner loop at 0. You can initialize count to 1 and start at i+1. Actually this is important as it means that the count for subsequent instances of array[i] will be less than the initial count, so they won't get added to the list as equal modes.

I've edited the code to detect the case where every element of the array is distinct, in which case there's no mode.

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

2 Comments

In my method it always returned some number as the mode though it occurred onetime in the array.But now I get that the reason was that I returned an integer instead of an array or list. Thank you very much for your clear explanation . It was really helpful.
"there has to be a mode unless the array is empty" Incorrect. If no number in a set of numbers occurs more than once, that set has no mode. E.g. 1, 2, 4, 7 has no mode. --- Easy enough to fix: Initialize maxCount to 2, not 0.
1

In Java 8+, it can be done like this:

public static int[] modes(int[] marksArray) {
    Entry<Long, List<Integer>> max = Arrays.stream(marksArray).boxed()
            .collect(groupingBy(identity(), TreeMap::new, counting())).entrySet().stream()
            .filter(e -> e.getValue() > 1)
            .collect(groupingBy(Entry::getValue, TreeMap::new, mapping(Entry::getKey, toList())))
            .lastEntry();
    return (max == null ? new int[0] : max.getValue().stream().mapToInt(Integer::intValue).toArray());
}

Test

public static void main(String[] args) {
    // Samples from https://www.mathsisfun.com/mode.html
    //          and https://www.purplemath.com/modules/meanmode.htm
    test(); // []
    test(1, 2, 4, 7); // []
    test(6, 3, 9, 6, 6, 5, 9, 3); // [6]
    test(1, 3, 3, 3, 4, 4, 6, 6, 6, 9); // [3, 6]
    test(13, 18, 13, 14, 13, 16, 14, 21, 13); // [13]
    test(8, 9, 10, 10, 10, 11, 11, 11, 12, 13); // [10, 11]
}
public static void test(int... marksArray) {
    System.out.println(Arrays.toString(modes(marksArray)));
}

Output

[]
[]
[6]
[3, 6]
[13]
[10, 11]

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.