[백준 | Javascript] 2108

박기영·2022년 8월 29일
0

백준

목록 보기
82/127

정렬. 5단계
2108번. 통계학

문제

2108번 문제 링크

solution

const fs = require("fs");
let input = fs.readFileSync("/dev/stdin").toString().trim().split("\n").map((item) => Number(item));

const iter = input.shift();

// 산술평균 //
// 모든 원소의 합을 구한 뒤 배열의 길이로 나누면 된다.
let sum = 0;

for(let i = 0; i < iter; i++){
    sum += input[i];
}

const avg = Math.round(sum / iter);

// 굳이 분기 처리를 하는 이유는 문제에도 나와있다.
// Math.round(-1/3)을 하면 0이 아니라, -0이 나온다.
// 이 때 0이 출력되어야하므로, 이 부분을 예외처리 해줘야한다.
if(avg === -0){
    console.log(0);
} else {
    console.log(avg);
}

// 중앙값 //
// input을 오름차순 or 내림차순으로 정렬 후 가운데 값을 구하면 된다.
input.sort((a,b) => a - b);

// input의 길이는 홀수이기 때문에, floor를 통해 중앙에 있는 인덱스 값으로 변경해준다.
// 예를들어, input의 길이가 5라면 5/2 = 2.5이므로 인덱스로 사용할 수 없다.
// 또한 1,2,3,4,5 중 3에 해당하는 값을 얻어야하므로, 인덱스는 2가 된다.
// 따라서, Math.floor() 처리를 해야지 알맞은 인덱스 값을 얻을 수 있다.
let idx = Math.floor(iter / 2);

console.log(input[idx]);

// 최빈값 // 
// Map 객체의 key-value를 생성하는 것으로 최대 개수를 가지는 원소를 찾아낼 것.
let map = new Map();

// 초기 최대 개수를 1로 설정해놓음.
// input의 모든 원소가 한 번씩만 나온다면 최대 개수는 1이됨.
let max = 1;

// input 배열에 있는 값들이 차례대로 number 변수로 사용된다.
for (let number of input) {
    // 만약 map에 number라는 key가 이미 존재한다면...
    // 즉, 같은 number가 두 번 이상 나올 때부터는...
    if (map.has(number)) {
        // max와 map.get(number) + 1 중 더 큰 숫자를 새로운 max로 지정
        // map.get(number) + 1을 하는 이유?
        // 이미 존재하는 number이므로 최소 1개는 존재하는데,
        // 같은 number가 1개가 더 발견됐기 때문에 1 증가시킨다.
        max = Math.max(max, map.get(number) + 1);
      
        // number를 key로 갖는 것의 value를 1 증가시킨다.
        map.set(number, map.get(number) + 1);
    } else {
        // 만약 map에 number라는 key가 없다면...
        // value를 1로 설정한다.
        map.set(number, 1);   
    }
}

let maxArr = [];

// map 변수의 key와 value가 변수로써 사용된다.
for (let [key, value] of map) {
  // value가 max와 같다면 
  if (value === max) { 
      // maxArr에 후보로 넣어준다. 여러 key들이 같은 최대 개수를 가질 수 있기 때문.
      maxArr.push(key);   
  }
}

// 만약 maxArr의 길이가 1이라면, 하나의 key만이 최대 개수를 가지고 있는 것이고
// 그게 아니라면, 여러 key가 최대 개수를 가지고 있는 것이므로,
// 후자의 경우 두 번째로 작은 숫자를 출력한다.
// 이는 input을 오름차순으로 정렬해놨기 때문에 가능한 것.
console.log(maxArr.length === 1 ? maxArr[0] : maxArr[1]);

// 범위 //
// input 배열의 최댓값과 최솟값의 차이를 구하면 된다.
// 위에서 sort로 인하여 배열이 오름차순 정렬이 되었으므로,
// 가장 앞에 있는 값이 최솟값, 가장 뒤에 있는 값이 최댓값이 된다.
let maxNum = input[input.length - 1];
let minNum = input[0];

console.log(maxNum - minNum);

주의할 점

다양한 풀이를 봤는데, Map 객체를 사용하는 분도 계시고 Set 객체를 사용하시는 분도 계신다.
필자는 Map이 이해가 더 빨랐기 때문에 이를 사용했다.
Map 객체의 다양한 메서드에 대한 설명은 이 블로그를 참고하면 좋을 것 같다.
추가로, 많은 분들이 문제를 대충 읽고, 문제 하단에 써있던 -0에 대한 설명을 지나치셨을거라고 생각하는데
이 부분이 생각보다 복병이었다. 필자는 영문도 모른채 10번을 고치고서야 이걸 발견했다..
-0.4xx를 반올림하면 -0이 된다는 사실을 잊지말자.
-0과 0은 완전히 다르다!!

참고 자료

참고 자료 1
참고 자료 2
참고 자료 3

profile
나를 믿는 사람들을, 실망시키지 않도록

0개의 댓글