当我的整数数组是多峰数组并且没有模式时,我的 Java 查找模式的方法失败

My Java method to find mode fails when my integer array is multimodal and when there's no mode

我正在尝试编写一个 java 方法来查找未排序整数数组中的众数。当数组中只有一种模式时,这很好用。但是当数组中没有模式时,它会给出一个随机数。

而且我还需要确保我的方法也适用于多模式数组。但是我发现很难将代码编辑为 return 一组模式。

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;
}

在Java8+中,可以这样做:

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());
}

测试

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)));
}

输出

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

如果数组中有多个模式,那么您的代码 return 是第一个,这并非不合理。

为了return所有模式你需要维护一个列表。

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;            
}

注意,内循环不需要从0开始,可以将count初始化为1,从i+1开始。实际上这很重要,因为它意味着 array[i] 的后续实例的计数将小于初始计数,因此它们不会作为相等模式添加到列表中。

我编辑了代码以检测数组的每个元素都不同的情况,在这种情况下没有模式。