통계학

21 June 2019

문제 : https://www.acmicpc.net/problem/2108

이번은 네가지 통계 값을 구하는 문제를 풀어보도록 하겠습니다.

import java.io.*;

public class Main {

    private static int[] positiveArr = new int[4001];
    private static int[] negativeArr = new int[4001];

    public static void main(String args[]) throws IOException {

        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out));

        int size = Integer.parseInt(reader.readLine());

        int[] arr = new int[size];
        double sum = 0;
        int maxFrequency = 0;
        int firstValue = Integer.MAX_VALUE;
        int secondValue = Integer.MAX_VALUE;
        for (int i = 0; i < size; i++) {
            int val = Integer.parseInt(reader.readLine());
            arr[i] = val;
            sum += val;
            if (val > 0) {
                positiveArr[val]++;
                if (positiveArr[val] > maxFrequency) {
                    maxFrequency = positiveArr[val];
                    firstValue = val;
                    secondValue = Integer.MAX_VALUE;
                } else if (positiveArr[val] == maxFrequency) {
                    if (val < firstValue) {
                        secondValue = firstValue;
                        firstValue = val;
                    } else if (val < secondValue) {
                        secondValue = val;
                    }
                }
            } else {
                negativeArr[-val]++;
                if (negativeArr[-val] > maxFrequency) {
                    maxFrequency = negativeArr[-val];
                    firstValue = val;
                    secondValue = Integer.MAX_VALUE;
                } else if (negativeArr[-val] == maxFrequency) {
                    if (val < firstValue) {
                        secondValue = firstValue;
                        firstValue = val;
                    } else if (val < secondValue) {
                        secondValue = val;
                    }
                }
            }
        }
        writer.write(String.valueOf(Math.round(sum / size)) + "\n");

        qSort(arr, 0, size - 1);
        writer.write(String.valueOf(arr[size / 2]) + "\n");

        if (secondValue != Integer.MAX_VALUE) {
            writer.write(String.valueOf(secondValue) + "\n");
        } else {
            writer.write(String.valueOf(firstValue) + "\n");
        }

        writer.write(String.valueOf(arr[size - 1] - arr[0]) + "\n");

        writer.flush();
        writer.close();
        reader.close();
    }

    private static void qSort(int[] arr, int start, int end) {
        if (start < end) {
            int partition = getPartition(arr, start, end);

            qSort(arr, start, partition - 1);
            qSort(arr, partition + 1, end);
        }
    }

    private static int getPartition(int[] arr, int start, int end) {
        int pivot = arr[end];
        int i = start - 1;
        for (int k = start; k < end; k++) {
            if (arr[k] < pivot) {
                i++;
                int temp = arr[i];
                arr[i] = arr[k];
                arr[k] = temp;
            }
        }
        int temp = arr[i + 1];
        arr[i + 1] = arr[end];
        arr[end] = temp;

        return i + 1;
    }
}
이번 문제는 각각 4가지의 값을 구하게 됩니다.
가장 처음은 전체의 산술 평균, 전체의 값을 모두 더하여 사이즈로 나눠주고 Math.round 메서드를 통해 반올림을 해주면 됩니다.
두번째는 중간에 위치하는 값 찾기, quick sort를 통해 전체를 정렬해주고 size/2에 위치하는 값을 가져오도록 합니다.
세번째는 가장 많이 등장한 최빈값 찾기, 전체의 값을 arr에 저장할 때 저장할 때마다 각각의 값에 대한 등장횟수를 다른 array에 저장하고, 해당 값에서 max값을 찾습니다.
max값을 가지는 value에 대해서 값을 저장하고, 같은 값이 등장할 경우 크기를 비교해 firstValue, secondValue에 각각 나눠서 저장해줍니다.
마지막으로, 최대값과 최소값의 차이는 정렬된 arr의 마지막 번호에서 0번을 빼주면 가능합니다.