平均值,中位数和模式

时间:2016-09-03 07:16:28

标签: java java-7 mean median mode

嗨我的模态值上的代码有问题。这是我的代码:

public class basicStatistics {
 public static void main(String[] args) {
    Scanner in = new Scanner(System.in);
    int n = in.nextInt();
    int[] arr = new int[n];
    int[] arrCount = new int[n];
    int maxCount = 0;
    double median = 0.0, mean = 0.0;
    for(int i = 0; i < n; i++) {
        arr[i] = in.nextInt();
        mean = mean + arr[i];
    }
    mean = mean/n;
    for(int i = 0; i < n; i++) {
        for(int j = 0; j < n; j++){
            if(arr[i] == arr[j]){
                arrCount[i]++;
            }
        if(maxCount < arrCount[i])
            maxCount = i;
        }
    }
    Arrays.sort(arr);
    if(n%2 == 0) {
        median = arr[n/2] + arr[n/2-1]; 
        median = median/2;
    } else {
        median = arr[n/2];
    }
    System.out.printf("%.1f\n", mean);
    System.out.printf("%.1f\n", median);
    System.out.println(arr[maxCount]);
 }
}

问题是当输入为:http://pastebin.com/HCqTrimY时,我无法正确获取模态值。我使用了pastebin,因为它输入了2500个数字。对于模式,我的代码输出数组值259而不是2184,但是如果输入是n = 10且数字= 64630 11735 14216 99233 14470 4978 73429 38120 51135 67060我得到模式值正确或其他情况。

我还希望利用Java8结构将代码转换为更高效的代码。先谢谢你了!

3 个答案:

答案 0 :(得分:0)

嗨,我回答了自己的问题。答案是将数组排序放在方法之上以获取maxCount:

    ...
    mean = mean/n;
    Arrays.sort(arr);
    for(int i = 0; i < n; i++) {
        for(int j = 0; j < n; j++){
            if(arr[i] == arr[j]){
                arrCount[i]++;
            }
        if(maxCount < arrCount[i])
            maxCount = i;
        }
    }
    if(n%2 == 0) { ...

现在唯一的问题是将其转换为Java8结构。编辑:当我尝试输入n = 10时出现一个新问题;数字是64630 11735 14216 99233 14470 4978 73429 38120 51135 67060它没有得到正确的模态值,应该是4978它输出11735。

编辑:要修复新错误,我必须在评估if(arr [i] == arr [j]){...}之前添加此代码if(i!= j){...}。 / p>

答案 1 :(得分:0)

“将此转换为Java8结构”是什么意思?使用像mean + = arr [i]这样的增量也会更有效;而不是mean = mean + arr [i];

对于你的问题:试试这个:

import statistics

def one_seq(n):
    main = []
    number = str("{0:b}".format(n))
    i = 0
    sub_main = []
    while i != len(number):
            if number[i] == 1: # you want to check against the string '1' not the number 1
                sub_main.append(number[i])
            else:
                main.append(sub_main)
                sub_main = []
                continue # this will skip the i+=1 and cause an infinite loop
            i+=1
    greatest_one = [len(element) for element in main ]
    return statistics.mode(greatest_one)  # There's no reason to use mode here.
                                          # You want the greatest element in the list
                                          # Not the most common.

答案 2 :(得分:0)

如果您想使用Java 8,您可以缩短代码。首先,mean:在这里,您可以从stream - 数组int创建arr,然后只需调用average方法:

double mean = IntStream.of(arr).average().getAsDouble();

median与您的代码几乎相同;我只是使用三元表达式(... ? ... : ...)而不是多行if/else将其放在更少的行上:

Arrays.sort(arr);
int len = arr.length;
double median = len % 2 == 0 ? (arr[len/2-1] + arr[len/2]) / 2. : arr[len/2];

mode有点困难,最后但并非最不重要,因为你似乎需要最小的模式,以防有多个号码出现最常见的情况。虽然您的双for - 循环方法也可行,但它具有二次复杂性,这可能成为较大数据集的问题。相反,您应该使用Map来计算不同的数字。在Java 8中,使用Collectors.groupingByCollectors.counting可以非常轻松地完成此操作。然后,只需确定计数的maxfilter具有该计数的数字,然后获取min的数量。

Map<Integer, Long> counts = IntStream.of(arr).boxed()
        .collect(Collectors.groupingBy(x -> x, Collectors.counting()));
Long max = counts.values().stream().max(Comparator.naturalOrder()).get();
int mode = counts.entrySet().stream()
        .filter(e -> e.getValue().equals(max))
        .min(Comparator.comparing(Entry::getKey)).get().getKey();