[백준 문제 풀이] 25206번 너의 평점은?

Junu Kim·2025년 7월 3일
0
post-thumbnail

[25206] 너의 평점은?

난이도: ★★★☆☆ • solved on: 2025-07-03




문제 요약

  • 문제 유형: 구현, 문자열 처리
  • 요구사항: P등급을 제외한 과목들의 (학점 × 평점) 총합을 전체 학점의 총합으로 나누어 소수점 여섯 자리까지 출력해야 한다.

사용 개념

  1. 자료구조
    • BufferedReader, String[]
  2. 알고리즘/기법
    • 구현
    • 문자열 분리
  3. 핵심 키워드
    • 가중 평균
    • GPA 계산

풀이 아이디어 및 코드

방법 1 : Switch-Case와 문자열 처리

  1. 문제 분해
    • 입력된 각 줄에서 과목명, 학점, 평점 문자열 분리
    • 평점이 "P"면 해당 과목 무시
    • 평점 문자열에 '+' 포함 여부에 따라 0.5 가산
    • 문자 매핑(A→4.0, B→3.0 등)으로 기본 점수 결정
    • (학점 × 평점)을 누적하고 총학점 누적
    • 최종적으로 총점/총학점 출력
  1. 핵심 로직 흐름
    while ((line = br.readLine()) != null) {
        tokens = line.split(" ");
        credit = Double.parseDouble(tokens[1]);
        gradeStr = tokens[2];
        if (gradeStr.equals("P")) continue;
        point = (gradeStr.contains("+") ? 0.5 : 0.0) + baseValue(gradeStr.charAt(0));
        totalCredits += credit;
        totalScore += credit * point;
    }
    print(totalScore / totalCredits);
  1. 예외 처리
    • 평점 "P" 과목은 학점/점수 계산에서 제외
import java.util.*;
import java.lang.*;
import java.io.*;

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

        double totalCourse = 0.0;
        double totalScore = 0.0;
        String s;
        double coursePoint;
        String scorePoint;

        while((s=br.readLine())!= null){
            double point=0.0;
            String[] list = s.split(" ");
            coursePoint=Double.valueOf(list[1]);
            scorePoint = list[2];
            if(scorePoint.equals("P")){
                continue;
            } else if(scorePoint.contains("+")){
                point += 0.5;
            }
            char letter = scorePoint.charAt(0);
            switch (letter) {
                case 'A': point += 4.0; break;
                case 'B': point += 3.0; break;
                case 'C': point += 2.0; break;
                case 'D': point += 1.0; break;
                case 'F': point += 0.0; break;
                default:
                    throw new IllegalArgumentException("Wrong Point: " + point);
            }
            totalCourse += coursePoint;
            totalScore += coursePoint*point;
        }
        System.out.printf("%.6f",totalScore/totalCourse);
    }
}

방법 2 : Map을 이용한 간결화 및 고정 라인 수 처리

  1. 문제 분해

    • 모든 평점 문자열("A+", "A0", …, "F")을 Map<String, Double>에 미리 매핑
    • 입력은 20줄 고정이므로 for문으로 20회 반복
    • Map에 평점 키가 있을 때만 학점·점수 누적
  1. 핵심 로직 흐름
    gradeMap = { "A+":4.5, "A0":4.0, …, "F":0.0 }
    for i in 1..20:
        tokens = readLine().split(" ")
        credit = parseDouble(tokens[1])
        gradeStr = tokens[2]
        if gradeMap.containsKey(gradeStr):
            totalCredits += credit
            totalScore += credit * gradeMap.get(gradeStr)
    print(totalScore / totalCredits)
  1. 예외 처리
    • "P" 평점은 Map에 없으므로 자연스럽게 무시
import java.io.*;
import java.text.DecimalFormat;
import java.util.*;

public class Main {
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        Map<String, Double> gradeMap = Map.of(
            "A+", 4.5, "A0", 4.0,
            "B+", 3.5, "B0", 3.0,
            "C+", 2.5, "C0", 2.0,
            "D+", 1.5, "D0", 1.0,
            "F", 0.0
        );
        double totalCredits = 0, totalScore = 0;
        for (int i = 0; i < 20; i++) {
            String[] tokens = br.readLine().split(" ");
            double credit = Double.parseDouble(tokens[1]);
            String grade = tokens[2];
            if (gradeMap.containsKey(grade)) {
                totalCredits += credit;
                totalScore += credit * gradeMap.get(grade);
            }
        }
        String result = new DecimalFormat("0.000000").format(totalScore / totalCredits);
        System.out.println(result);
    }
}

시간·공간 복잡도

방법 1 & 2

  • 시간 복잡도 : O(N) (N=20)
  • 공간 복잡도 : O(1)

복잡도 자체는 두 방법 모두 동일하지만, 코드의 가독성과 재구성 측면에서 방법 2가 더 효율적이다.


어려웠던 점

  • EOF 기반 입력 처리와 고정 라인 수 입력 처리 중 선택의 어려움
  • Java 9 이상의 Map.of 활용법 숙지에 시간이 소요됨
  • DecimalFormat을 이용한 포맷팅 방법 학습 필요

배운 점 및 팁

  • Map을 사용하면 switch보다 코드가 간결해지고 유지보수성이 향상됨.
  • 입력 라인이 고정되어 있으면 for문으로 명확하게 처리하는 것이 안전함.
  • DecimalFormat을 사용하면 출력 포맷을 유연하게 지정할 수 있음.

DecimalFormat 클래스를 활용한 출력 포맷팅

  • 클래스 위치: java.text.DecimalFormat (Java SE 8 이상)
  • 주요 역할: 숫자를 지정한 패턴에 맞춰 문자열로 포맷팅하거나, 문자열을 숫자로 파싱 (printf 대신 사용 가능하다.)

1. 패턴(Pattern) 문법

  • 0 : 필수 숫자. 자릿수가 부족하면 0으로 채움
  • # : 선택 숫자. 자릿수가 부족하면 생략
  • . : 소수점 구분자
  • , : 그룹(천 단위 등) 구분자
  • E : 지수 표기
  • %/ : 곱하기 100/1000 후 퍼센트/퍼밀 기호 붙임
  • ; : 양수/음수 서브패턴 구분 (예: #,##0.00;(#,##0.00))

2. 주요 생성자 및 메서드

  1. 생성자
    new DecimalFormat();                   // 기본 로케일의 패턴·심볼 사용 
    new DecimalFormat(String pattern);     // 지정한 패턴 사용  
    new DecimalFormat(String p, DecimalFormatSymbols sym);  // 패턴+심볼 커스터마이징  
  2. 패턴 적용
    df.applyPattern("#0.000000");          // 최소 1정수자리, 6소수자리 고정  
  3. 포맷팅
    String s = df.format(3.141592);        // "3.141592"  
  4. 나머지 주요 기능
    • setRoundingMode(RoundingMode mode) : 반올림 모드 지정 (기본 HALF_EVEN)
    • setGroupingUsed(true/false) : 그룹(천 단위) 구분자 사용 여부
    • setDecimalSeparatorAlwaysShown(true/false) : 정수만 있을 때도 소수점 표시 여부

참고 및 링크


추가 연습 방향

  • 평점 체계가 변경(예: 4.0 → 5.0 만점)된 경우 GPA 계산 로직 수정
  • 과목 수가 가변인 경우에도 동적으로 처리하는 프로그램 구현
profile
생각이 현실이 될 수 있도록 노력하는 중입니다.

0개의 댓글