문제 해석
- 문제 자체는 간단하다. N개 만큼 숫자를 입력받는다. (단, N은 홀수이다.)
- 모두 입력 받았다면, 아래의 순서대로 출력한다.
1. 산술평균 : N개의 수들의 합을 N으로 나눈 값
2. 중앙값 : N개의 수들을 증가하는 순서로 나열했을 경우 그 중앙에 위치하는 값
3. 최빈값 : N개의 수들 중 가장 많이 나타나는 값
4. 범위 : N개의 수들 중 최댓값과 최솟값의 차이
- 또, 0은 부호가 없도록 출력하며, 산술 평균의 경우 소수점 첫째자리에서 반올림한다.
- 정수의 절댓값은 4,000을 넘지 않는다는 뜻은 입력 값이 -4000~+4000 범위에서만 입력받는다는 뜻이다.
- 최빈값을 구할 때 고려해야할 점은 여러 개 있을 때에는 최빈값 중 두 번째로 작은 값을 출력한다는 것
코드
import java.util.*;
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
int N = Integer.parseInt(br.readLine());
int[] numbers = new int[N];
for(int i = 0; i < N; i++){
numbers[i] = Integer.parseInt(br.readLine());
}
br.close();
bw.write(findAvg(numbers) + "\n");
bw.write(findMiddle(numbers) + "\n");
bw.write(findFrequence(numbers) + "\n");
bw.write(findDiffer(numbers) + "\n");
bw.flush();
bw.close();
}
static int findAvg(int[] array){
double sum = 0;
int avg = 0;
for(int i = 0; i < array.length; i++){
sum += array[i];
}
avg = (int)Math.round(sum/array.length);
return avg;
}
static int findMiddle(int[] array){
Arrays.sort(array);
return array[array.length/2];
}
static int findFrequence(int[] array){
Map<Integer, Integer> mp = new HashMap<>();
if (array.length == 1) {
return array[0];
}
for (int i = 0; i < array.length ; i++) {
if (mp.containsKey(array[i])) {
mp.put(array[i], mp.get(array[i]) + 1);
} else {
mp.put(array[i], 1);
}
}
int maxValue = Collections.max(mp.values());
ArrayList<Integer> arrayList = new ArrayList<>();
for (Map.Entry<Integer, Integer> newMap : mp.entrySet()) {
if (newMap.getValue() == maxValue) {
arrayList.add(newMap.getKey());
}
}
Collections.sort(arrayList);
if (arrayList.size() > 1)
return arrayList.get(1);
else
return arrayList.get(0);
}
static int findDiffer(int[] array){
Arrays.sort(array);
return Math.abs(array[array.length-1] - array[0]);
}
}
- 백준을 풀면서 처음 쓴게 Entry라는 것인데, 주석으로 다른 코드 설명과 함께 작성해두었다.
- Map의 Entry key와 value의 쌍이다.
- Map.entrySet() 메서드는 이 클래스에 속하는 요소를 가지는 맵의 collection view(=키를 값에 매핑 하는 객체)를 리턴합니다.
- Map.Entry의 참조를 얻는 유일한 방법은 이 collection view의 반복자로부터 얻는 방법이다.
- 즉, 쉽게 말하면 key와 value의 쌍으로 가지는 자료구조(?)를 반복문을 돌릴 때 사용하는 것이 Map.Entry이고 이러한 Map.Entry값의 똑같은 형태인 key와 value의 쌍으로 매핑하는 객체를 리턴하는 것이 Map.entrySet() 메서드이다.
결과
느낀 점
- 최빈 값이 가장 헷갈렸던 문제였다.
- 조건도 있었고, 생각해야할 것들이 생각보다는 좀 많았다. (다른 통계 값에 비해서)
- 받은 배열에서 값을 최빈값을 구해야할지 처음엔 감도 안왔었는데 그때 Map이 돌파구가 되어주었다.