Java数组统计程序多众数与无众数场景的众数计算实现
现有众数功能的核心缺陷
- 原
calculateMode方法仅维护单个众数变量,遇到多个数值出现频次相同时,只会保留第一个遍历到的、达到最高频次的值,无法兼容多众数场景 - 无众数判定逻辑:当所有数值的出现次数均为1时,方法会默认返回遍历到的第一个数值,不会输出预期的"None"提示
- 返回值为单个
double类型,结构上无法承载多个众数的输出需求 - 原实现采用双层循环统计频次,时间复杂度为O(n²),统计效率偏低
最优实现逻辑
- 调整
calculateMode方法的返回值为List<Double>,用空列表代表无众数的场景 - 采用HashMap实现O(n)复杂度的频次统计,替代原双层循环逻辑
- 统计完成后先提取全局最高出现频次,判断该频次是否大于1:若最高频次≤1,直接判定为无众数
- 筛选所有出现频次等于全局最高值的数值,全部加入结果集作为最终众数列表
- 主方法中根据返回的列表内容做差异化输出:列表为空打印"None",多值时拼接成逗号分隔的字符串打印
修正后的完整代码
import java.util.*; public class ArrayStatistics { public static void main(String[] args) { Scanner input = new Scanner(System.in); System.out.print("Enter the size of your array >> "); int size = input.nextInt(); double[] myArray = new double[size]; System.out.print("Enter the integer values >> "); for (int i = 0; i < size; i++) { myArray[i] = input.nextInt(); } System.out.println("\nIntegers:"); for (int i = 0; i < size; i++) { System.out.println(myArray[i]); } double mean = calculateMean(myArray); System.out.println("\nMean: " + mean); // 修正后的众数输出逻辑 List<Double> modes = calculateMode(myArray); if (modes.isEmpty()) { System.out.println("Mode: None"); } else { System.out.print("Mode: "); for (int i = 0; i < modes.size(); i++) { if (i != 0) System.out.print(", "); System.out.print(modes.get(i)); } System.out.println(); } double median = calculateMedian(myArray); System.out.println("Median: " + median); double SD = calculateSD(myArray); System.out.format("Standard Deviation: %.6f", SD); input.close(); } public static double calculateMean(double myArray[]) { int sum = 0; for(int i = 0; i < myArray.length; i++) { sum = (int) (sum + myArray[i]); } return ((double) sum) / myArray.length; } // 重写支持多众数、无众数场景的calculateMode方法 public static List<Double> calculateMode(double myArray[]) { Map<Double, Integer> frequencyMap = new HashMap<>(); // 统计每个数值的出现次数 for (double num : myArray) { frequencyMap.put(num, frequencyMap.getOrDefault(num, 0) + 1); } // 找到全局最高出现频次 int maxFrequency = 0; for (int count : frequencyMap.values()) { if (count > maxFrequency) { maxFrequency = count; } } // 最高频次小于等于1说明没有众数,返回空列表 if (maxFrequency <= 1) { return new ArrayList<>(); } // 收集所有达到最高频次的数值 List<Double> modeList = new ArrayList<>(); for (Map.Entry<Double, Integer> entry : frequencyMap.entrySet()) { if (entry.getValue() == maxFrequency) { modeList.add(entry.getKey()); } } return modeList; } // 修正原中位数计算的边界bug:兼容数组长度为奇数的场景 public static double calculateMedian(double myArray[]) { Arrays.sort(myArray); int len = myArray.length; if (len % 2 == 1) { return myArray[len / 2]; } return (myArray[len/2] + myArray[len/2 - 1]) / 2.0; } public static double calculateSD(double myArray[]) { double sum = 0.0; double standardDeviation = 0.0; int length = myArray.length; for(double num : myArray) { sum += num; } double mean = sum / length; for(double num : myArray) { standardDeviation += Math.pow(num - mean, 2); } return Math.sqrt(standardDeviation / length); } }
补充验证说明
- 输入数组
[1,2,2,3,3,4,5,6,7,8]时,方法会返回包含2.0、3.0的列表,输出为Mode: 2.0, 3.0- 输入全不重复的数组(如
[1,2,3,4,5])时,最高频次为1,返回空列表,输出为Mode: None- 输入单个众数的数组时,输出逻辑和原有功能保持一致,无兼容性问题
- 注:由于本场景输入的都是整数,存入double数组后不存在浮点精度误差,用HashMap做频次统计的key不会出现匹配异常
内容的提问来源于stack exchange,提问作者Shane
相关产品推荐
相关产品推荐

