[회고록] 왜 이건 안되고 저건 될까 (feat 프로그래머스)

Updated:

도데체 왜 이 코드는 안되고 저 코드는 되는거지??

프로그래머스 코딩테스트 문제를 풀다가 분명히 같은 결과를 출력하는데 왜 이건 틀리고 저건 맞는거야?? 라는 질문을 내뱉었다.
정말 궁금했다. 이 의문점을 내뱉게 한건 바로 이 문제다

https://programmers.co.kr/learn/courses/30/lessons/60057

아래는 틀렸다는 답을 받은 소스코드이다.


int solution(string s) {
    int answer;
    int min_characters = s.size(); // 압축된 문자열중 가장 문자수가 적은 수를 저장
    int mid = s.size() / 2; 

    for(int i = 1; i <= mid; i++){ // 반으로 자른 단위까지만(반을 넘어가게 자르는 경우는 없다)
        string each_str = ""; // 각 단위별로 압축된 문자열
        string prev_str; // 각 단위별로 자른 왼쪽 문자열
        string current_str; // 각 단위별로 자른 오른쪽 문자열
        int count = 1; // 연속되는 두 문자열의 반복 횟수

        prev_str = s.substr(0, i); // 우선 가장 왼쪽 문자열을 넣어준다

        for(int j = i; j < s.size(); j += i){  
            current_str = s.substr(j, i); // 단위별로 반복해서 자른다
            if(prev_str.compare(current_str) == 0){ // 두 문자열이 같다는 것은 연속한다는 것을 의미한다
                count++; // 그러므로 연속 횟수를 증가
            }
            else{ // 두 문자열이 다르다면
                if(count >= 2){  // 연속하는 횟수를 체크하여 2개 이상일 경우
                    char c = count + '0';
                    each_str += (c + prev_str); // 직전 연속횟수 + 직전 문자열을 차례로 저장
                    count = 1; // 연속 횟수는 다시 초기화
                }
                else{     // 연속횟수가 1개 이하이면
                    each_str += prev_str; // 그냥 그대로 직전 문자열 저장
                }
            }
            prev_str = current_str; // 그렇게 반복하여 준다
        }
        // 위에서 다 반복을 하였어도 마지막 문자열은 아직 처리되지 않았다
        // 그러므로 마지막 연속 횟수와 마지막 문자열을 체크해준다
        if(count >= 2){ 
            char c = count + '0';
            each_str += (c + prev_str); // 직전 연속횟수 + 직전 문자열을 차례로 저장
        }
        else{
            each_str += prev_str;
        }

        min_characters = min(min_characters, (int)each_str.size()); // 압축된 문자열의 사이즈중 가장 작은 사이즈를 저장해준다
    }
    answer = min_characters;

    return answer;
}


다음은 맞았다는 답을 받은 소스코드이다.


int solution(string s) {
    int answer;
    int min_characters = s.size(); // 압축된 문자열중 가장 문자수가 적은 수를 저장
    int mid = s.size() / 2; 

    for(int i = 1; i <= mid; i++){ // 반으로 자른 단위까지만(반을 넘어가게 자르는 경우는 없다)
        string each_str = ""; // 각 단위별로 압축된 문자열
        string prev_str; // 각 단위별로 자른 왼쪽 문자열
        string current_str; // 각 단위별로 자른 오른쪽 문자열
        int count = 1; // 연속되는 두 문자열의 반복 횟수

        prev_str = s.substr(0, i); // 우선 가장 왼쪽 문자열을 넣어준다

        for(int j = i; j < s.size(); j += i){  
            current_str = s.substr(j, i); // 단위별로 반복해서 자른다
            if(prev_str.compare(current_str) == 0){ // 두 문자열이 같다는 것은 연속한다는 것을 의미한다
                count++; // 그러므로 연속 횟수를 증가
            }
            else{ // 두 문자열이 다르다면
                if(count >= 2){  // 연속하는 횟수를 체크하여 2개 이상일 경우
                    each_str += (to_string(count) + prev_str); // 직전 연속횟수 + 직전 문자열을 차례로 저장
                    count = 1; // 연속 횟수는 다시 초기화
                }
                else{     // 연속횟수가 1개 이하이면
                    each_str += prev_str; // 그냥 그대로 직전 문자열 저장
                }
            }
            prev_str = current_str; // 그렇게 반복하여 준다
        }
        // 위에서 다 반복을 하였어도 마지막 문자열은 아직 처리되지 않았다
        // 그러므로 마지막 연속 횟수와 마지막 문자열을 체크해준다
        if(count >= 2){ 
            each_str += (to_string(count) + prev_str); // 직전 연속횟수 + 직전 문자열을 차례로 저장
        }
        else{
            each_str += prev_str;
        }

        min_characters = min(min_characters, (int)each_str.size()); // 압축된 문자열의 사이즈중 가장 작은 사이즈를 저장해준다
    }
    answer = min_characters;

    return answer;
}


바꾼 부분은 정말 어이가 없게도 이것이다.

char c = count + '0';
each_str += (c + prev_str); // 직전 연속횟수 + 직전 문자열을 차례로 저장

count 정수형 변수를 문자형 변수로 변환하는 코드이다. 그리고 나서 (문자 + 문자열) 해서 대입해준다. 이렇게 해도 string 으로 변환되는데 왜 틀린다고 하는 건지 잘 모르겠다.

그런데 저것과 똑같은 기능을 하는 string 라이브러리 함수를 쓰면 그건 또 정답이란다.

each_str += (to_string(count) + prev_str);


아직도 원인은 모른다. 다만 이제부터 확실히 해야할 것은 굳이 같은 기능을 하는 코드라면 c++ 라이브러리에 있는 함수를 쓰는 것이 코딩테스트에서 정답을 받기에 훨씬 수월할 것이라는 점이다.

실무에서도 마찬가지이겠지만 말이다. 굳이 코드를 더 길게 해서 보기에 별로 안좋고 효율도 별로일 수 있는 자체 구현보다는 효율성이 보장된 라이브러리 함수를 쓰는 것이 훨씬 나을 것이다.

앞으로는 명심해야 겠다.

Categories:

Updated:

Leave a comment