当我的整数数组是多峰数组并且没有模式时,我的 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]
的后续实例的计数将小于初始计数,因此它们不会作为相等模式添加到列表中。
我编辑了代码以检测数组的每个元素都不同的情况,在这种情况下没有模式。
我正在尝试编写一个 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]
的后续实例的计数将小于初始计数,因此它们不会作为相等模式添加到列表中。
我编辑了代码以检测数组的每个元素都不同的情况,在这种情况下没有模式。