[백준] 2108번 : 통계학 - JAVA

2024. 4. 12. 17:15·백준

 

 

2108 통계학

 

 

이번 문제는 아래 4가지 요소들을 찾는 문제로 난이도가 낮아보였는데 정답 비율도 낮아서 처음엔 의아했다.

 

  1. 산술평균 : N개의 수들의 합을 N으로 나눈 값
  2. 중앙값 : N개의 수들을 증가하는 순서로 나열했을 경우 그 중앙에 위치하는 값
  3. 최빈값 : N개의 수들 중 가장 많이 나타나는 값
  4. 범위 : N개의 수들 중 최댓값과 최솟값의 차이

 

산술평균 소스

산술평균은 입력된 모든 값들을 더한 후 배열의 길이로 나누어 주었다.

 

입력된 값의 범위가 -4000 ~ 4000이고 입력값의 최대 개수가 50만개이기 때문에 sum 변수의 자료형을 double로 선언하였다.

int n = Integer.parseInt(br.readLine());
final int[] arr = new int[n];
double sum = 0;

// 산술평균
for (int a : arr) {
    sum += a;
}

sb.append(Math.round(sum / arr.length)).append("\n");

 

중앙값 소스

입력값들을 저장한 배열의 중앙값을 출력하면 된다.

Arrays.sort(arr);

sb.append(arr[arr.length / 2]).append("\n");

 

최빈값 소스

최빈값은 가장 많이 나타난 수이기 때문에 카운팅 정렬을 사용하여 문제를 해결하였다.

 

주의할 점으로는 최빈값이 중복되는 경우 2번째 나타난 값을 출력하는 것이다.

/*
최빈값을 구하기 위한 카운팅 배열
정수의 최댓값이 4000이기 때문에 음수처리의 경우 -1이 나오면 4001 인덱스에 삽입
 */
final int[] arrCounting = new int[8001];

for (int i = 0; i < n; i++) {
    arrCounting[Integer.parseInt(br.readLine()) >= 0 ? input : 4000 - input]++;
}

// 등장 횟수가 이전 요소와 동일한지 판단여부
boolean isEqual = false;
// 최빈값을 저장할 배열의 인덱스
int idx = 0;
// 등장 횟수 최대값 체크용 변수
int max = 0;

int[] arrMax = new int[arrCounting.length];

for (int i = 0; i < arrCounting.length; i++) {
    if (arrCounting[i] == 0) continue;

    int cnt = 0;

    while (arrCounting[i]-- > 0) {
        cnt++;
    }

    if (cnt < max) continue;

    if (cnt > max) {
        max = cnt;
        isEqual = false;

        // 최빈값이 새로 생긴 경우 배열 초기화
        arrMax = new int[arrCounting.length];
        idx = 0;
    } else {
        isEqual = true;
    }

    arrMax[idx++] = i > 4000 ? -i + 4000 : i;
}

int[] arrResult = new int[idx];

// 최빈값들을 저장한 배열의 길이가 카운팅 배열과 동일하기 때문에 새로운 결과 배열을 만든다.
for (int i = 0; i < idx; i++) {
    arrResult[i] = arrMax[i];
}

// 결과 배열 오름차순 정렬
Arrays.sort(arrResult);

// 최빈값
int mode;

// 최빈값이 중복되는 경우 2번째 요소 선택
if (isEqual && arrResult.length > 1) {
    mode = arrResult[1];
} else {
    mode = arrResult[0];
}

 

 

범위 소스

범위의 경우 정렬한 배열의 첫 번째 그리고 마지막 요솟수의 양수 여부를 체크하고 해당 값들의 차이를 구하면 된다.

int range;
int range1 = arr[arr.length - 1] - arr[0];
int range2 = arr[arr.length - 1] > arr[0] ? range1 : arr[0] - arr[arr.length - 1];

// 둘 다 양수
if (arr[arr.length - 1] >= 0 && arr[0] >= 0) {
    range = range2;
}
// 최대값만 양수
else if (arr[arr.length - 1] >= 0) {
    range = range1;
}
// 둘 다 음수
else {
    range = range2;
}

 

 

성공 소스

public class Main {

    /**
     * 최빈값을 가져오는 메소드
     * @param arrCounting 카운팅 배열
     * @return 최빈값 정수
     */
    private static int getMode(int[] arrCounting) {
        // 등장 횟수가 이전 요소와 동일한지 판단여부
        boolean isEqual = false;
        // 등장 횟수 최대값 체크용 변수
        int max = 0;
        // 최빈값을 저장할 배열의 인덱스
        int idx = 0;
		// 최빈값 저장 배열
        int[] arrMax = new int[arrCounting.length];

        for (int i = 0; i < arrCounting.length; i++) {
            if (arrCounting[i] == 0) continue;

            int cnt = 0;

            while (arrCounting[i]-- > 0) {
                cnt++;
            }

            if (cnt < max) continue;

            if (cnt > max) {
                max = cnt;
                isEqual = false;

                // 최빈값이 새로 생긴 경우 배열 초기화
                arrMax = new int[arrCounting.length];
                idx = 0;
            } else {
                isEqual = true;
            }

            arrMax[idx++] = i > 4000 ? -i + 4000 : i;
        }

        int[] arrResult = new int[idx];
        for (int i = 0; i < idx; i++) {
            arrResult[i] = arrMax[i];
        }

        Arrays.sort(arrResult);

        if (isEqual && arrMax.length > 1) {
            return arrResult[1];
        } else {
            return arrResult[0];
        }
    }

    public static void main(String[] args) throws IOException{
        final BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        final StringBuilder sb = new StringBuilder();

        int n = Integer.parseInt(br.readLine());
        final int[] arr = new int[n];

        /*
        최빈값을 구하기 위한 카운팅 배열
        정수의 최댓값이 4000이기 때문에 음수처리의 경우 -1이 나오면 4001 인덱스에 삽입
         */
        final int[] arrCounting = new int[8001];
        double sum = 0;

        // 입력
        for (int i = 0; i < n; i++) {
            int input = Integer.parseInt(br.readLine());
            arr[i] = input;

            if (input >= 0) {
                arrCounting[input]++;
            } else {
                arrCounting[4000 - input]++;
            }
        }

        // 산술평균
        for (int a : arr) {
            sum += a;
        }

        sb.append(Math.round(sum / arr.length)).append("\n");

        // 중앙값
        Arrays.sort(arr);
        sb.append(arr[arr.length / 2]).append("\n");

        // 최빈값
        sb.append(getMode(arrCounting)).append("\n");

        // 범위
        int range;
        int range1 = arr[arr.length - 1] - arr[0];
        int range2 = arr[arr.length - 1] > arr[0] ? range1 : arr[0] - arr[arr.length - 1];

        // 둘 다 양수
        if (arr[arr.length - 1] >= 0 && arr[0] >= 0) {
            range = range2;
        }
        // 최대값만 양수
        else if (arr[arr.length - 1] >= 0) {
            range = range1;
        }
        // 둘 다 음수
        else {
            range = range2;
        }

        sb.append(range);

        System.out.println(sb);
        br.close();
    }

}
저작자표시 비영리 변경금지 (새창열림)

'백준' 카테고리의 다른 글

[백준] 18110번 : solved.ac - JAVA  (0) 2024.04.19
[백준] 15829번 : Hashing - JAVA  (0) 2024.04.17
[백준] 11576번 : Base Conversion - JAVA  (0) 2024.03.31
[백준] 11005번 : 진법 변환 2 - JAVA  (0) 2024.03.31
[백준] 2745번 : 진법 변환 - JAVA  (0) 2024.03.31
'백준' 카테고리의 다른 글
  • [백준] 18110번 : solved.ac - JAVA
  • [백준] 15829번 : Hashing - JAVA
  • [백준] 11576번 : Base Conversion - JAVA
  • [백준] 11005번 : 진법 변환 2 - JAVA
masjeong
masjeong
교양이란 화를 내지 않으면서도 자신의 신념을 잃지 않은 채 어떤 얘기라도 들을 수 있는 능력을 말한다 - 로버트 프로스트
  • masjeong
    나자바바라쿠배
    masjeong
  • 전체
    오늘
    어제
    • 전체보기 (28)
      • Spring Boot (3)
      • Spring Batch (1)
      • MSA (3)
      • Docker (1)
      • 백준 (16)
      • 자료구조 (3)
      • Kafka (0)
      • DB (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    진법변환
    티스토리챌린지
    정렬
    spring cloud Gateway
    이분탐색
    mariadb
    백준
    cloud native application
    spring batch
    Queue
    알고리즘
    큐
    MSA
    SpringCloud
    11561
    백준3041
    오블완
    백준11723
    이진탐색
    gradle 오류
    executortype
    15829
    18111
    springboot
    Cloud Native Architecture
    ExecutionContext
    2449
    18110
    ratelimiter
    Java
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
masjeong
[백준] 2108번 : 통계학 - JAVA
상단으로

티스토리툴바