위클리 챌린지 2주차

Updated:

프로그래머스에서 할 수 있는 위클리 챌린지 2주차 코딩 테스트를 해봤다.

문제를 간단히 말하면, 학생들의 점수가 담긴 정수형 2차원 배열 scores가 매개변수로 주어지고, 이때, 학생들의 학점을 구하여 하나의 문자열로 만들어서 return 하도록 solution 함수를 완성하는 것이다.

class Solution {
    public String solution(int[][] scores) {
        String answer = "";
            for(int i=0; i<scores.length; i++) {
                int max = 0;
                int min = 101;
                int sum = 0;
                int cnt = scores.length;
                for(int j=0; j<scores.length; j++) {
                    if(i != j){
                        max = Math.max(max, scores[j][i]);
                        min = Math.min(min, scores[j][i]);
                    }
                    sum += scores[j][i];
                }         
                if(scores[i][i] < min || scores[i][i] > max){
                    cnt--;
                    sum -= scores[i][i];
                }
                switch((sum/cnt)/10){
                    case 10:
                    case 9:
                        answer += "A";
                        break;
                    case 8:
                        answer += "B";
                        break;
                    case 7:
                        answer += "C";
                        break;
                    case 6:
                    case 5:
                        answer += "D";
                        break;
                    default:
                        answer += "F";
                        break;
                }
            }
        return answer;
    }
}

나는 이렇게 코딩을 했고, 프로그래머스에서 테스트를 한 결과 평균적으로 1.9ms의 시간이 걸렸다.

프로그래머스의 좋은 점은 이렇게 풀이를 완료하면 다른 사람의 풀이도 볼 수 있는 점인데,

좋아요가 가장 많은 분의 코딩을 보고 새삼 놀랐다.

class Solution {
    public String solution(int[][] scores) {
        StringBuilder builder = new StringBuilder();
        for(int i=0; i<scores.length; i++) {
            int max = 0;
            int min = 101;
            int sum = 0;
            int divide = scores.length;
            for(int j=0; j<scores.length; j++) {
                int score = scores[j][i];
                if(i != j) {
                    if(score < min) {
                        min = score;
                    }
                    if(score > max) {
                        max = score;
                    }
                }
                sum += score;
            }
            if(scores[i][i] < min || scores[i][i] > max) {
                sum -= scores[i][i];
                divide--;
            }
            double score = (double) sum / divide;
            builder.append(score >= 90 ? "A" : score >= 80 ? "B" : score >= 70 ? "C" : score >= 50 ? "D" : "F" );
        }
        return builder.toString();
    }
}

// 평균속도 : 0.03ms

StringBuilder은 개념만 살짝 알고 사용한 적은 없어서 이번 코테에서 사용할 생각을 못했는데 이렇게 사용 예를 보니 내가 짠 코드보다 훨씬 좋은 코드란 걸 느꼈다.

String은 소위 불변(immutable)객체다.

String str1 = “abc”; String str2 = “def”; 2개의 String 객체가 있을 때, 만약 str1 + str2;와 같은 연산을 하게 되면 새로운 String을 생성한다.

즉, String 객체와 String 객체를 더하는 (+) 행위는 메모리 할당과 메모리 해제를 발생시키며 연산이 많아질수록 성능적으로 좋지 않다.

그래서 나온 것이 StringBuilder이다.

StringBuilder는 String과 문자열을 더할 때 새로운 객체를 생성하는 것이 아니라 기존의 데이터에 더하는 방식을 사용하기 때문에 속도도 빠르며 상대적으로 부하가 적다.

따라서 긴 문자열을 더하는 상황이 발생할 경우 StringBuilder를 적극적으로 사용하자

append()는 문자열을 더하는 역학을 하며 만들어진 문자열을 출력하려면 toString()을 사용한다.

실제로 내가 작성한 코드를 StringBuilder를 통해 다시 작성해서 실행해보면

class Solution {
    public String solution(int[][] scores) {
        StringBuilder sb = new StringBuilder();
            for(int i=0; i<scores.length; i++) {
                int max = 0;
                int min = 101;
                int sum = 0;
                int cnt = scores.length;
                for(int j=0; j<scores.length; j++) {
                    if(i != j){
                        max = Math.max(max, scores[j][i]);
                        min = Math.min(min, scores[j][i]);
                    }
                    sum += scores[j][i];
                }         
                if(scores[i][i] < min || scores[i][i] > max){
                    cnt--;
                    sum -= scores[i][i];
                }
                switch((sum/cnt)/10){
                    case 10:
                    case 9:
                        sb.append("A");
                        break;
                    case 8:
                        sb.append("B");
                        break;
                    case 7:
                        sb.append("C");
                        break;
                    case 6:
                    case 5:
                        sb.append("D");
                        break;
                    default:
                        sb.append("F");
                        break;
                }
            }
        return sb.toString();
    }
}
// 평균속도 : 0.03~0.06ms

평균적으로 1.9ms가 걸렸던 것이 0.03~0.06ms로 줄어들게 된 것을 알 수 있다.

Leave a comment