[ Baekjoon ] 2108번 (SILVER IV ) : 통계학 (Java)

ma.caron_g·2022년 1월 9일
0
post-thumbnail

1. Problem 📃

[ 통계학 ]

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


[ 문제 ]

수를 처리하는 것은 통계학에서 상당히 중요한 일이다. 통계학에서 N개의 수를 대표하는 기본 통계값에는 다음과 같은 것들이 있다. 단, N은 홀수라고 가정하자.

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

N개의 수가 주어졌을 때, 네 가지 기본 통계값을 구하는 프로그램을 작성하시오.


2. Input 📇

[ 입력 ]

첫째 줄에 수의 개수 N(1 ≤ N ≤ 500,000)이 주어진다. 단, N은 홀수이다. 그 다음 N개의 줄에는 정수들이 주어진다. 입력되는 정수의 절댓값은 4,000을 넘지 않는다.


3. Output 📠

[ 출력 ]

첫째 줄에는 산술평균을 출력한다. 소수점 이하 첫째 자리에서 반올림한 값을 출력한다.

둘째 줄에는 중앙값을 출력한다.

셋째 줄에는 최빈값을 출력한다. 여러 개 있을 때에는 최빈값 중 두 번째로 작은 값을 출력한다.

넷째 줄에는 범위를 출력한다.


4. Example 📚

[ 입출력 예시 ]

예제 입력예제 출력
5
1
3
8
-2
2
2
2
1
10
1
4000
4000
4000
4000
0
5
-1
-2
-3
-1
-2
-2
-2
-1
2

5. Solution 🔑

  1. 리스트를 하나는 입력된 값들을 다루고(list), 하나는 최빈값(inf)을 다루기 위해 두 개 선언한다.
    입력된 값들의 개수를 세어주기 위한 배열(count)를 선언한다. 이때, -4000~4000이므로 배열 인덱스는 음수가 존재하지 않으므로 배열의 길이가 8001까지 되도록 선언한다.

  2. 몇 개의 수를 받을지에 대한 변수(N)을 선언하여 입력 받아준다.
    입력 받으면서 평균을 구하기 위해 입력된 수들의 합을 바로 바로 구해줄 변수(sum)을 선언한다.
    sum으로 평균을 구할 것이기 때문에 double형으로 선언하여준다.

  3. N만큼 루프를 돌려 수를 입력 받고, 그 수를 sum에 더한다. list에 값을 추가하고 그 후 입력된 수에 4000을 더해서 count배열 인덱스 만큼에 넣어준다
    (ex. 0 -> count[4000], -4000 -> count[0])

  4. list는 큰 수와 작은 수의 차이를 비교해줘야하므로 Collections.sort()시켜서 오름차순 정렬시켜준다.
    이제 구하고자 하는 값을 하나씩 구해본다.

  5. 평균을 구하는데, 위에 더해놨던 sum을 N(값의 개수)만큼 나누어준다. Math.round()를 이용하여 첫째 자리에서 반올림한 값을 가져온다.

  6. mid값은 정렬한 list의 (N/2)번째 값을 가져오면 중간값을 쉽게 가져올 수 있다.

  7. 최빈값을 알기위해 count변수를 하나씩 돌면서 가장 많이 나온 값을 확인한다. 이때 max변수를 0으로 선언해서 count배열 변수의 값이 max보다 크면 최빈값을 알기 위한 inf리스트를 초기화 후 inf에 해당 인덱스를 저장하고, 만약 max와 같은 값이 나온다면 inf에 또 추가하여준다.
    (Set을 선언하여 배열 8001개를 다 돌 필요없이 Set에 저장된 값만 확인해보았는데 시간이 더욱 오래 걸렸다..)

  8. inf 리스트에는 최빈값이 담겨있는데 이때, inf의 사이즈가 1이라면 inf.get(0)을 통해 최빈값을 반환받고, 최빈값이 여러개 즉, inf의 사이즈가 1보다 크다면 문제에서 2번째 값을 출력하라 하였으므로, inf.get(1)을 통해 두 번째 값을 반환 받아 popular변수에 담아준다.

  9. 입력 받은 수 중 가장 작은 수와 가장 큰 수의 차이(gap)을 구하는 법은 처음에 sort시킨 list의 0번째 값이랑 list.size()-1 번째 값의 차이를 구해주면 gap이 구해진다.

  10. 출력문을 한 번 이용해서 한 번에 모든 값들을 출력하여준다.

6. Code 💻

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;

public class Main {

	public static void main(String[] args) throws NumberFormatException, IOException {
		
//		산술평균 : N개의 수들의 합을 N으로 나눈 값
//		중앙값 : N개의 수들을 증가하는 순서로 나열했을 경우 그 중앙에 위치하는 값
//		최빈값 : N개의 수들 중 가장 많이 나타나는 값
//		범위 : N개의 수들 중 최댓값과 최솟값의 차이
		
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		
		ArrayList<Integer> list = new ArrayList<Integer>();
		ArrayList<Integer> inf = new ArrayList<Integer>();
		int[] count = new int[8001];
		int N = Integer.parseInt(br.readLine());
		double sum = 0;
		for(int i=0; i<N; i++) {
			list.add(Integer.parseInt(br.readLine()));
			sum += list.get(i);
			count[list.get(i)+4000]++;
		}
		
		Collections.sort(list)
		
		int avg = (int)(Math.round(sum/N));
        
		int mid = list.get(N/2);
		
		int popular = 0;
		int max = 0;
		for(int i=0; i<count.length; i++) {
			if(count[i] > max) {
				max = count[i];
				inf.clear();
				inf.add(i);
			}
			else if(count[i] == max) {
				inf.add(i);
			}
			else {
				continue;
			}
		}
		Collections.sort(inf);
		
		if(inf.size()>1) {
			popular = inf.get(1) - 4000;
		}
		else if(inf.size() == 1 ) {
			popular = inf.get(0) - 4000;
		}
		
		int gap = list.get(N-1) - list.get(0);
		
		System.out.print(avg + "\n" + mid + "\n" + popular + "\n" + gap);

	}

}
profile
다른 사람이 만든 것을 소비하는 활동보다, 내가 생산적인 활동을 하는 시간이 더 많도록 생활화 하자.

0개의 댓글