[회고록] 왜 이건 안되고 저건 될까 (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++ 라이브러리에 있는 함수를 쓰는 것이 코딩테스트에서 정답을 받기에 훨씬 수월할 것이라는 점이다.
실무에서도 마찬가지이겠지만 말이다. 굳이 코드를 더 길게 해서 보기에 별로 안좋고 효율도 별로일 수 있는 자체 구현보다는 효율성이 보장된 라이브러리 함수를 쓰는 것이 훨씬 나을 것이다.
앞으로는 명심해야 겠다.
Leave a comment