-
[99클럽/코딩테스트 챌린지/C++] 모의고사 문제 풀이 및 리팩토링을 통한 가독성 향상과 코드 간소화2024년 11월 16일
- 유니얼
-
작성자
-
2024.11.16.:06
728x90문제 링크 :
https://school.programmers.co.kr/learn/courses/30/lessons/42840
문제 요약
수포자 삼인방이 각각 일정한 규칙으로 답을 찍습니다. 문제의 정답 배열 answers가 주어질 때, 가장 많은 문제를 맞힌 사람(들)을 찾아서 오름차순으로 반환하는 문제입니다.
접근법
- 각 수포자의 정답 규칙을 벡터로 정의합니다.
- 정답 배열을 순회하며 각 수포자가 정답을 맞힌 횟수를 기록합니다.
- 가장 높은 점수를 계산하고, 해당 점수를 얻은 수포자를 반환합니다.
#include <algorithm> #include <iostream> #include <queue> #include <tuple> #include <vector> using namespace std; int number1(vector<int>& answers) { int count = 0; for(int i = 0; i < answers.size(); i++) { int ret = (i % 5) + 1; if(ret == answers[i]) { count++; } } return count; } int number2(vector<int>& answers) { int count = 0; vector<int> tre = { 2, 1, 2, 3, 2, 4, 2, 5 }; for (int i = 0; i < answers.size(); i++) { int index = i % tre.size(); if (tre[index] == answers[i]) count++; } return count; } int number3(vector<int>& answers) { int count = 0; vector<int> tre = { 3,3,1,1,2,2,4,4,5,5 }; for (int i = 0; i < answers.size(); i++) { int index = i % tre.size(); if (tre[index] == answers[i]) count++; } return count; } vector<int> solution(vector<int> answers) { vector<int> answer; vector<pair<int, int>> pi; int max = 0; for(int i = 0; i < 3; i++) { int anw = 0; if (i == 0) anw = number1(answers); else if (i == 1) anw = number2(answers); else if (i == 2) anw = number3(answers); if(anw >= max) { if (pi.empty()) pi.push_back({ i + 1 ,anw}); else { if(pi[0].second < anw) { int count = pi.size(); for (int j = 0; j < count; j++) { pi.pop_back(); } pi.push_back({ i + 1,anw }); } else if(pi[0].second == anw) { pi.push_back({ i + 1 ,anw}); } } max = anw; } } for (auto a : pi) { answer.push_back(a.first); } sort(answer.begin(), answer.end()); return answer; }
기존 코드 문제점
- 중복된 코드:
- number1, number2, number3 함수가 동일한 로직을 반복합니다.
- 조건문(if (i == 0), else if)로 각 수포자 점수를 계산해 코드가 복잡합니다.
- 복잡한 데이터 관리:
- vector<pair<int, int>> pi를 사용해 점수를 관리하며 불필요한 메모리 접근(pop_back)과 복잡한 비교 로직을 추가했습니다.
- 가독성 부족:
- number1, number2, number3가 각각 별도의 함수로 정의되어 있어 코드 흐름을 따라가기가 어렵습니다.
리팩토링 핵심
- 전역 벡터로 정답 패턴 관리: 각 수포자의 정답 패턴을 전역 vector로 정의하여 반복 코드 제거.
- 단일 루프로 점수 계산: 반복문 하나로 모든 수포자의 점수를 계산해 코드 가독성을 높임.
- STL 함수 활용: max_element를 사용해 가장 높은 점수를 직관적으로 계산.
- 데이터 구조 간소화: vector<int> 하나로 점수 관리, 복잡한 pair 구조 제거.
#include <algorithm> #include <iostream> #include <queue> #include <tuple> #include <vector> using namespace std; vector<int> num1 = { 1,2,3,4,5 }; vector<int> num2 = { 2, 1, 2, 3, 2, 4, 2, 5 }; vector<int> num3 = { 3, 3, 1, 1, 2, 2, 4, 4, 5, 5 }; vector<int> solution(vector<int> answers) { vector<int> answer; vector<int> theys(3); for(int i = 0; i < answers.size(); i++) { if (answers[i] == num1[i % num1.size()]) theys[0]++; if (answers[i] == num2[i % num2.size()]) theys[1]++; if (answers[i] == num3[i % num3.size()]) theys[2]++; } int maxValue = *max_element(theys.begin(), theys.end()); for(int i = 0; i < theys.size(); i++) { if(theys[i] == maxValue) { answer.push_back(i + 1); } } return answer; }
리팩토링을 통해 배운 점
- 중복 제거의 중요성:
- 반복적인 코드 구조는 데이터와 반복문으로 대체할 수 있다.
- 동일한 작업을 하는 코드를 함수로 나누는 대신, 데이터 중심으로 간소화하는 것이 효과적이다.
- 가독성을 높이는 데이터 구조 설계:
- 복잡한 자료구조보다 직관적인 자료구조(vector<int>)를 사용하는 것이 가독성과 유지보수 측면에서 유리하다.
- STL 함수 활용:
- max_element와 같은 STL 함수를 적극 활용하면 코드가 간결하고 읽기 쉬워진다.
느낀 점
이번 리팩토링을 통해 "간단하고 직관적인 코드가 더 좋은 코드"라는 것을 배웠습니다. 처음 작성한 코드도 정답이었지만, 중복 코드와 복잡한 구조 때문에 유지보수가 어렵고 가독성이 낮았습니다. 리팩토링을 통해 코드가 단순해지고 문제 해결에 더 집중할 수 있었습니다. 앞으로도 코드를 작성할 때 가독성과 간결함을 항상 고려해야겠다고 느꼈습니다.
반응형다음글이전글이전 글이 없습니다.댓글
스킨 업데이트 안내
현재 이용하고 계신 스킨의 버전보다 더 높은 최신 버전이 감지 되었습니다. 최신버전 스킨 파일을 다운로드
받을 수 있는 페이지로 이동하시겠습니까?
("아니오" 를 선택할 시 30일 동안 최신 버전이
감지되어도 모달 창이 표시되지 않습니다.)