【问题标题】:Finding the mode from an user-input array if there are multiple modes or no mode如果有多种模式或没有模式,则从用户输入数组中查找模式
【发布时间】:2021-07-27 02:55:15
【问题描述】:

我正在开发一个项目,该项目提示用户创建并用整数填充数组,然后显示该数组的平均值、众数、中位数和标准差。它首先询问用户数组的大小,输入的数字将声明和初始化数组。然后程序将迭代几次,要求用户声明一个整数值,每个值都将存储到数组中,直到数组被填满。然后程序将打印数组的内容,以及平均值、众数、中位数和标准差。

我的代码似乎满足所有这些要求。但是,我正在努力的一件事是模式。虽然它确实打印出数组中重复次数最多的数字,但它没有考虑具有相同重复次数的多个模式,也没有考虑没有模式会发生什么。

现在,如果两个数字各输入两次,则显示的模式是第一个重复多次的数字。例如,如果我有一个 10 个整数的数组大小,并且我输入的整数是 1、2、2、3、3、4、5、6、7、8,它将打印出模式的“2.0”打印“2.0”和“3.0”。如果没有模式,它只是输入第一次输入的数字,而不是说“无”。

实现这一目标的最佳行动方案是什么?

这是我的代码:

import java.util.*;
public class ArrayStatistics {

public static void main(String[] args) {
    double total = 0;
    
    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);
    
    double mode = calculateMode(myArray);
    System.out.println("Mode: " + mode);
    
    double median = calculateMedian(myArray);
    System.out.println("Median: " + median);
    
    double SD = calculateSD(myArray);
    System.out.format("Standard Deviation: %.6f", SD);
    }

public static double calculateMean(double myArray[]) {
    int sum = 0;
    
    for(int i = 0; i<myArray.length; i++) {
        sum = (int) (sum + myArray[i]);
    }
    double mean = ((double) sum) / (double)myArray.length;
    
    return mean;
}

public static double calculateMode(double myArray[]) {
    int modeCount = 0;
    int mode = 0;
    int currCount = 0;
    
    for(double candidateMode : myArray) {
        currCount = 0;
        for(double element : myArray) {
            if(candidateMode == element) {
                currCount++;
            }
        }
        if(currCount > modeCount) {
            modeCount = currCount;
            mode = (int) candidateMode;
        }
    }
    return mode;
}

public static double calculateMedian(double myArray[]) {
    Arrays.sort(myArray);
    
    int val = myArray.length/2;
    double median = ((myArray[val]+myArray[val-1])/2.0);
    
    return median;
}

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

【问题讨论】:

    标签: java arrays mode


    【解决方案1】:

    首先是代码,然后是解释。

    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.LinkedHashMap;
    import java.util.List;
    import java.util.Map;
    import java.util.Scanner;
    import java.util.stream.Collectors;
    
    public class ArrayStatistics {
        public static void main(String[] args) {
            int total = 0;
            Scanner input = new Scanner(System.in);
            System.out.print("Enter the size of your array >> ");
            int size = input.nextInt();
            int[] myArray = new int[size];
            Map<Integer, Integer> frequencies = new HashMap<>();
            System.out.print("Enter the integer values >> ");
            for (int i = 0; i < size; i++) {
                myArray[i] = input.nextInt();
                if (frequencies.containsKey(myArray[i])) {
                    int frequency = frequencies.get(myArray[i]);
                    frequencies.put(myArray[i], frequency + 1);
                }
                else {
                    frequencies.put(myArray[i], 1);
                }
                total += myArray[i];
            }
            System.out.println("\nIntegers:");
            for (int i = 0; i < size; i++) {
                System.out.println(myArray[i]);
            }
    
            double mean = calculateMean(size, total);
            System.out.println("\nMean: " + mean);
    
            List<Integer> mode = calculateMode(frequencies);
            System.out.println("Mode: " + mode);
    
            double median = calculateMedian(myArray);
            System.out.println("Median: " + median);
    
            double stdDev = calculateSD(mean, total, size, myArray);
            System.out.format("Standard Deviation: %.6f", stdDev);
        }
    
        public static double calculateMean(int count, int total) {
            double mean = ((double) total) / count;
            return mean;
        }
    
        public static List<Integer> calculateMode(Map<Integer, Integer> frequencies) {
            Map<Integer, Integer> sorted = frequencies.entrySet()
                                                      .stream()
                                                      .sorted((e1, e2) -> e2.getValue() - e1.getValue())
                                                      .collect(Collectors.toMap(e -> e.getKey(),
                                                                                e -> e.getValue(),
                                                                                (i1, i2) -> i1,
                                                                                LinkedHashMap::new));
            Iterator<Integer> iterator = sorted.keySet().iterator();
            Integer first = iterator.next();
            Integer val = sorted.get(first);
            List<Integer> modes = new ArrayList<>();
            if (val > 1) {
                modes.add(first);
                while (iterator.hasNext()) {
                    Integer next = iterator.next();
                    Integer nextVal = sorted.get(next);
                    if (nextVal.equals(val)) {
                        modes.add(next);
                    }
                    else {
                        break;
                    }
                }
            }
            return modes;
        }
    
        public static double calculateMedian(int myArray[]) {
            Arrays.sort(myArray);
    
            int val = myArray.length / 2;
            double median = ((myArray[val] + myArray[val - 1]) / 2.0);
    
            return median;
        }
    
        public static double calculateSD(double mean, int sum, int length, int[] myArray) {
            double standardDeviation = 0.0;
            for (double num : myArray) {
                standardDeviation += Math.pow(num - mean, 2);
            }
            return Math.sqrt(standardDeviation / length);
        }
    }
    

    为了确定模式,您需要跟踪输入到数组中的整数的出现次数。我使用Map 来执行此操作。我还在输入整数时计算总数。我在需要它的方法中使用这个总数,例如calculateMean。每次需要时重新计算总数似乎都是额外的工作。

    您正在处理整数,那么为什么将myArray 声明为double 的数组?因此我将其更改为 int 的数组。

    您的问题是如何确定模式。因此我重构了方法calculatMode。为了确定模式,您需要询问频率,因此需要询问方法参数。由于您声称可以有零种、一种或多种模式,因此该方法返回List。首先,我根据值对Map 条目进行排序,即myArray 中特定整数的出现次数。我按降序对条目进行排序。然后我将所有排序的条目收集到LinkedHashMap,因为这是一个按添加顺序存储其条目的映射。因此LinkedHashMap 中的第一个条目将是出现次数最多的整数。如果第一个映射条目的出现次数为 1(一个),则表示没有模式(根据我找到的 definition):

    如果列表中没有数字重复,则列表没有模式。

    在没有模式的情况下,方法calculateMode返回一个空的List

    如果第一个条目的出现次数多于一个,我将整数添加到List。然后我遍历剩余的映射条目并将整数添加到List,如果它的出现等于第一个映射条目的出现。一旦条目中出现的次数不等于第一个条目的次数,我就退出while 循环。现在List 包含myArray 中出现次数最多的所有整数。

    这是一个示例运行(使用您问题中的示例数据):

    Enter the size of your array >> 10
    Enter the integer values >> 1 2 2 3 3 4 5 6 7 8
    
    Integers:
    1
    2
    2
    3
    3
    4
    5
    6
    7
    8
    
    Mean: 4.1
    Mode: [2, 3]
    Median: 3.5
    Standard Deviation: 2.211334
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-09
      • 2017-09-10
      • 1970-01-01
      • 1970-01-01
      • 2014-06-16
      • 2014-04-28
      • 2011-09-28
      • 1970-01-01
      相关资源
      最近更新 更多