[소프티어] 성적 평균 | JavaScript | toFixed()

예구·2023년 8월 8일
0

Softeer

목록 보기
8/13
post-thumbnail

문제출처

1. 문제

N명의 학생들의 성적이 학번순서대로 주어졌다.

학번 구간 [A, B]가 주어졌을 때 이 학생들 성적의 평균을 구하는 프로그램을 작성하라.

제약조건

1 ≤ N ≤ 10^6 인 정수
1 ≤ K ≤ 10^4 인 정수
1 ≤ Si ≤ 100 인 정수
1 ≤ Ai ≤ Bi ≤ N

입력형식

첫 번째 줄에 학생 수 N과 구간 수 K가 주어진다.
두 번째 줄에는 학생의 성적 Si (1 ≤ i ≤ N)가 주어진다. i + 2 (1 ≤ i ≤ K)번째 줄에는 i번째 구간 Ai, Bi가 주어진다.

출력형식

i번째 줄에 i번째 구간의 성적평균(소수셋째자리에서 반올림)을 출력한다.
차이가 0.01이하이면 정답으로 채점됨.

입력예제1

5 3
10 50 20 70 100
1 3
3 4
1 5

출력예제1

26.67
45.00
50.00



2. 풀이

Lv.3치곤 쉬운 문제라서 '이거 분명 시간초과 뜬다..'하고 제출했는데 통과해서 오히려 더 놀랐던 문제다.

  • 입력되는 값 중 첫 번째줄은 사용하지 않아서 받아오기만 하고 따로 변수를 선언하진 않았다.
  • 구간 수 만큼 for문을 돌면서 구간 시작(start)와 구간 끝(end)를 구했다.
  • 평균 계산은 학생의 성적 배열(grades_arr)을 slice()로 자르고, reduce()로 누적 합을 구한 다음, 구간 길이로 나눠줬으며, 마지막으로 toFix()를 사용하여 소수셋째자리에서 반올림했다.

전체 코드는 다음과 같다.

const readline = require("readline");

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdput,
});

let lines = [];

rl.on("line", (line) => {
  lines.push(line.split(" ").map(Number));
}).on("close", () => {
  let grades_arr = lines[1]; // 학생 성적 배열

  // 구간별 평균 구하기
  for (let i = 2; i < lines.length; i++) {
    let [start, end] = lines[i]; // [구간 시작, 구간 끝]

    // 평균 계산
    let avg = (
      grades_arr.slice(start - 1, end).reduce((acc, cur) => acc + cur, 0) /
      (end - start + 1)
    ).toFixed(2);

    console.log(avg);
  }

  process.exit();
});



3. toFixed()

이전까지 반올림 함수로 Math.round()만 알고 있었는데 이번 문제에서는 소수셋째자리에서 반올림을 해야했다.
찾아보니 toFixed()라는 함수를 알게 되었다.
이번에 Math.round()toFixed()를 비교해 보려고 한다.


3.1. Math.round()

Math.round(x)

파라미터로 입력받은 숫자의
소수점 이하의 값이 0.5보다 크면, 입력받은 수보다 다음으로 높은 절대값을 가지는 정수를 리턴
소수점 이하의 값이 0.5보다 작으면, 입력받은 수보다 절대값이 더 낮은 정수 리턴
소수점 이하의 값이 0.5와 같으면, 입력받은 수보다 큰 다음 정수 리턴

// 정수 반올림
console.log(Math.round(1.222)); // 1
console.log(Math.round(1,777)); // 2
console.log(Math.round(-1.111)); // -1
console.log(Math.round(-1.88)); // -2
console.log(Math.round(null)); // 0

// 자릿수 지정
console.log(Math.round(1.222 * 10) / 10); // 1.2
console.log(Math.round(1.777 * 10) / 10); // 1.8

3.2. 소수점 숫자 정밀도 문제

소수점 이하의 값을 올림(ceil), 내림(floor), 반올림(round) 처리할 때 부동 소수점(Floating Point)의 정밀도 문제 때문에 예상치 못한 결과가 나오기도 한디.

console.log(1.005 * 100); // 100.49999999999999
console.log(Math.round(1.005 * 100) / 100); // 1

3.3. toFixed()

numObj.toFixed([digits])
  • 부동소수점(Floating Point) 숫자를 고정소수점(Fixed Point) 숫자로 바꿔서 리턴
  • 파라미터로 숫자(digits)를 전달하면, digits만큼의 소수점 이하 자릿수를 가지는 문자열로 리턴
  • 원본 숫자(numberObj)의 소수점 이하 길이가 digits보다 길면 숫자를 반올림하고, 짧으면 뒤를 0으로 채워서 리턴
console.log(1.222.toFixed(1)); // 1.2
console.log(1.5.toFixed(2)); // 1.50
console.log(1.777.toFixed(1)); // 1.8



참고

https://hianna.tistory.com/446

profile
우당탕탕 FE 성장기

0개의 댓글