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



BufferedReader, String[]
- 문제 분해
- 입력된 각 줄에서 과목명, 학점, 평점 문자열 분리
- 평점이
"P"면 해당 과목 무시- 평점 문자열에
'+'포함 여부에 따라 0.5 가산- 문자 매핑(
A→4.0,B→3.0등)으로 기본 점수 결정(학점 × 평점)을 누적하고 총학점 누적- 최종적으로
총점/총학점출력
- 핵심 로직 흐름
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);
- 예외 처리
- 평점
"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);
}
}
문제 분해
- 모든 평점 문자열(
"A+","A0", …,"F")을Map<String, Double>에 미리 매핑- 입력은 20줄 고정이므로
for문으로 20회 반복Map에 평점 키가 있을 때만 학점·점수 누적
- 핵심 로직 흐름
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)
- 예외 처리
"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가 더 효율적이다.
Map.of 활용법 숙지에 시간이 소요됨DecimalFormat을 이용한 포맷팅 방법 학습 필요switch보다 코드가 간결해지고 유지보수성이 향상됨.for문으로 명확하게 처리하는 것이 안전함.DecimalFormat 클래스를 활용한 출력 포맷팅
- 클래스 위치:
java.text.DecimalFormat(Java SE 8 이상)- 주요 역할: 숫자를 지정한 패턴에 맞춰 문자열로 포맷팅하거나, 문자열을 숫자로 파싱 (printf 대신 사용 가능하다.)
1. 패턴(Pattern) 문법
0: 필수 숫자. 자릿수가 부족하면 0으로 채움#: 선택 숫자. 자릿수가 부족하면 생략.: 소수점 구분자,: 그룹(천 단위 등) 구분자E: 지수 표기%/‰: 곱하기 100/1000 후 퍼센트/퍼밀 기호 붙임;: 양수/음수 서브패턴 구분 (예:#,##0.00;(#,##0.00))
2. 주요 생성자 및 메서드
- 생성자
new DecimalFormat(); // 기본 로케일의 패턴·심볼 사용 new DecimalFormat(String pattern); // 지정한 패턴 사용 new DecimalFormat(String p, DecimalFormatSymbols sym); // 패턴+심볼 커스터마이징- 패턴 적용
df.applyPattern("#0.000000"); // 최소 1정수자리, 6소수자리 고정- 포맷팅
String s = df.format(3.141592); // "3.141592"- 나머지 주요 기능
setRoundingMode(RoundingMode mode): 반올림 모드 지정 (기본HALF_EVEN)setGroupingUsed(true/false): 그룹(천 단위) 구분자 사용 여부setDecimalSeparatorAlwaysShown(true/false): 정수만 있을 때도 소수점 표시 여부
Map.of 문서: https://docs.oracle.com/javase/9/docs/api/java/util/Map.htmlDecimalFormat 문서: https://docs.oracle.com/javase/8/docs/api/java/text/DecimalFormat.html