본문 바로가기

코딩테스트/백준

백준 : 2755번 이번 학기 평점은 몇 점? (JAVA)

목차

    JAVA 풀이 2755번 이번 학기 평점은 몇 점?

    https://www.acmicpc.net/problem/2755

    문제

    최백준이 이번 학기에 들은 과목과 학점 그리고 성적이 주어졌을 때,
    평균 평점을 계산하는 프로그램을 작성하시오.
    
    성적은 A+~F까지 총 13개가 있다.
    A+: 4.3, A0: 4.0, A-: 3.7
    B+: 3.3, B0: 3.0, B-: 2.7
    C+: 2.3, C0: 2.0, C-: 1.7
    D+: 1.3, D0: 1.0, D-: 0.7
    F: 0.0
    
    평균 평점은 각 과목의 학점*성적을 모두 더한 뒤에, 총 학점으로 나누면 된다.

    입력

    첫째 줄에, 백준이가 이번 학기에 들은 과목 수가 주어진다.
    둘째 줄부터 N개의 줄에 각 과목의 과목명, 학점, 성적이 주어진다.
    
    과목명은 알파벳 소문자와 숫자, 그리고 밑줄 (_)로만 이루어져 있으며,
    최대 100글자이고, 학점은 1보다 크거나 같고, 3보다 작거나 같은 자연수이다.
    
    성적은 문제에 설명한 13가지 중 하나이다.

    출력

    첫째 줄에 평균 평점을 소수점 셋째 자리에서 반올림해서 둘째 자리까지 출력한다.
    (평균 평점이 1.5이면 1.50을 출력한다.)

    예제 입력1

    7
    General_Physics_1 3 A+
    Introduction_to_Computer_Science_and_Eng 3 B0
    Reading_And_Writing 2 C0
    English_1 3 C+
    Analytic_Geometry_and_Calculus_1 3 B+
    Fortran_Programming 3 B+
    C_Language_Programming 3 A+

    예제 출력1

    3.28

     


    풀이 (리팩토링 전)

    import java.io.*;
    
    public class Main {
    	public static void main(String[] args) throws IOException {
    		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    		
    		// 과목 수
    		int subjectCount = Integer.parseInt(br.readLine());
    		// 평균 평점
    		double averageGrade = 0;
    		// 총 학점
    		int totalCredit = 0;
    		
    		for(int i = 0; i < subjectCount; i++) {
    			String[] subject = br.readLine().split(" ");
    			// 학점
    			int credit = Integer.parseInt(subject[1]);
    			
    			// 총 학점 구하기
    			totalCredit += credit;
                
    			// 성적
    			double gradeSum = 0;
    			
    			// F라면 0점
    			if(subject[2].equals("F")) continue;
                
    			// 성적 알파벳
    			char grade = subject[2].charAt(0);
    			// 성적 수식어
    			char gradeAdd = subject[2].charAt(1);
    			
    			if(grade == 'A') {
    				gradeSum = 4;
    			}else if(grade == 'B') {
    				gradeSum = 3;
    			}else if(grade == 'C') {
    				gradeSum = 2;
    			}else if(grade == 'D') {
    				gradeSum = 1;
    			}
    			
    			if(gradeAdd == '+') {
    				gradeSum += 0.3;
    			}else if(gradeAdd == '-') {
    				gradeSum -= 0.3;
    			}
    			
    			// 각 과목의 학점 * 성적을 모두 더하기
    			averageGrade += (credit * gradeSum);
    		}
    
    		// 평균 평점 구하기
    		averageGrade /= totalCredit;
            
    		// 소수점 셋째 자리에서 반올림하여 출력
    		System.out.printf("%.2f", averageGrade);
    	}
    }

    메인 메서드에서 모든 계산과 출력까지 하였다.


    풀이 (리팩토링 후)

    import java.io.*;
    
    public class Main {
    	public static void main(String[] args) throws IOException {
    		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    		
    		// 과목 수
    		int subjectCount = Integer.parseInt(br.readLine());
    		// 평균 평점
    		double averageGrade = calculateAverageGrade(br, subjectCount);
    
    		// 반올림하여 둘째 자리까지 출력
    		System.out.printf("%.2f", averageGrade);
    	}
    	
    	// 평균 평점 구하는 메서드
    	private static double calculateAverageGrade(BufferedReader br, int subjectCount) throws IOException {
    		// 총 학점
    		int totalCredit = 0;
    		// 평균 평점
    		double averageGrade = 0;
    		
    		for(int i = 0; i < subjectCount; i++) {
    			String[] subject = br.readLine().split(" ");
    			// 학점
    			int credit = Integer.parseInt(subject[1]);
    			// 성적
    			double gradeSum = calculateGrade(subject[2]);
    			// 각 과목의 학점 * 성적을 모두 더하기
    			averageGrade += credit * gradeSum;
    			// 총 학점 구하기
    			totalCredit += credit;
    		}
    		
    		// 평균 평점 반환
    		return averageGrade / totalCredit;
    	}
    	
    	// 성적을 구하는 메서드
    	private static double calculateGrade(String grade) {
    		// F는 0점
    		if(grade.equals("F")) return 0;
    		
    		// 성적 알파벳
    		char gradeChar = grade.charAt(0);
    		// 점수
    		double gradeSum = 0;
    		
    		switch (gradeChar) {
    		case 'A' :
    			gradeSum = 4;
    			break;
    		case 'B' :
    			gradeSum = 3;
    			break;
    		case 'C' :
    			gradeSum = 2;
    			break;
    		case 'D' :
    			gradeSum = 1;
    			break;
    		}
    		
    		// 성적 수식어
    		char gradeModifier = grade.charAt(1);
    		if(gradeModifier == '+') gradeSum += 0.3;
    		else if(gradeModifier == '-') gradeSum -= 0.3;
    		
    		// 점수 반환
    		return gradeSum;
    	}
    }

    변수의 이름을 조금 더 명확하게 수정하였고, 기능별로 메서드를 구분하였다.

     

    이때까지 첫 번째 방식으로 문제를 풀어왔는데, 'Clean Code'를 읽고 문제점에 대해 깨닫게 되었다.

    앞으로는 각 기능을 구분하고 의도를 파악하기 쉬운 코드를 작성할 수 있도록 노력해야겠다.