- Today
- Total
Byeo
2021 KAKAO Blind - 1. 신규 아이디 추천 본문
목차
개요
2021년 카카오 Blind 채용 첫 문제입니다. 첫 문제답게 간단히 구현하면 되는 문제인데, 최적화 여지를 생각하다가 오히려 한 군데에서 예외를 발생 시켜 버렸었네요.
정규식을 활용한 파이썬 풀이는 [이 포스트] 를 참고하시면 좋을 듯 합니다.
코드 설명
Step 1: 대문자를 소문자로 변경
Python 에서는 기본으로 string type에 lowercase()라는 메서드를 제공해주는데 반해, C++에서는 찾지 못했습니다. 그러나 그 구현이 간단하므로 단순히 for문 돌면서 직접 변경해줬습니다.
//step 1
if(tmp >= 'A' && tmp <='Z') tmp+= ('a'-'A');
tmp는 for문 도는 과정에서 현재의 문자입니다. 문자는 모두 ASCII 로 관리되고, 이 값은 [나무위키-아스키 코드 표]를 참고하시면 됩니다. 대문자는 이중에서 하면 65 ~ 90에 해당하고, 소문자는 97 ~ 122에 해당합니다.
간단히 대문자라면 'a'-'A' 의 차이(32) 만큼 더해주면 소문자로 바뀝니다.
Step 2: [0-9a-z._-] 만 허용
//step 2
if(!(tmp >= 'a' && tmp <='z' || tmp >='0' && tmp <='9' || tmp =='-' || tmp=='.' || tmp=='_')){
continue;
}
조건문으로 문자가 위 조건에 해당 하는지 확인하면 됩니다. 제 코드는 허용되지 않는 문자인 경우 바로 다음 for문을 실행하도록 하였습니다.
Step 3: 연속된 .(마침표) 제거
if(i>0 && answer[answer.length()-1] == '.' && tmp == '.'){
continue;
}
answer.push_back(tmp);
step 1과 step 2를 통과했으면 step 3에서 answer vector에 저장하기 시작합니다. 이 때, 이미 answer의 마지막에 '.'이 들어가 있었고, 지금 넣어야 할 문자가 '.'이라면 넣지 않습니다.
이 부분에서 실수를 한게 있는데, new_id의 직전 문자가 아니라 저장 중인 answer의 직전 문자를 봐야 합니다.
ab..!@..ef 를 예시로 들면, new_id의 직전 문자를 보는 경우 ab..!@..ef → ab.!@..ef → ab...ef → ab..ef 로 마침표 2개가 연속된 채로 남게 됩니다.
Step 4: 처음, 마지막 마침표 제거
//step 4
if(answer[0]=='.') answer.erase(0,1);
if(answer[answer.length()-1]=='.') answer.erase(answer.length()-1,1);
Step 3을 거치면서 문자열 내에 마침표가 연속된 경우는 없습니다. 따라서 반복문 없이 처음 1글자와 마지막 1글자만 보면 됩니다.
Step 5: 빈 문자열의 경우 'a' 추가
//step 5
if(answer.length() == 0){
answer.push_back('a');
}
만약에 step 4를 거치면서 answer가 빈 문자열이 된 경우 (length가 0인 경우), answer에 'a'를 넣어줍니다.
Step 6: 길이가 15를 넘는 경우 잘라내기
//step 6
if(answer.length() > 15){
answer.resize(15);
}
if(answer[answer.length()-1]=='.') answer.erase(answer.length()-1,1);
C++ string에서는 resize라는 함수를 제공해줍니다. 이를 사용해서 쉽게 원하는 길이만큼 잘라낼 수 있습니다.
문제에서 주의 사항을 안내한 대로, 잘라낸 뒤 마지막 문자가 마침표인지 다시 체크해야 합니다. 마찬가지로, Step 3을 거치면 연속된 마침표는 없기 때문에 마지막 한 문자만 체크하면 됩니다.
Step 7: 길이가 3보다 작은 경우 복사
//step 7
if(answer.length()<3){
answer.resize(3, answer[answer.length()-1]);
}
문자열의 길이가 3보다 작은 경우, 마지막 글자를 복사합니다. C++ String에서는 resize가 또 좋은 기능을 제공해주는데, resize하면서 기존보다 확장되는 경우에 그 공간을 무엇으로 채울지 지정할 수 있습니다. 여기서는 3으로 resize 해주면서, 원래의 마지막 문자 (answer.length()-1)로 채워주면 되겠죠?
코드
전체 코드입니다.
#include <string>
using namespace std;
string solution(string new_id) {
string answer = "";
int length = new_id.length();
for(int i=0; i<length; i++){
char tmp = new_id[i];
//step 1
if(tmp >= 'A' && tmp <='Z') tmp+= ('a'-'A');
//step 2
if(!(tmp >= 'a' && tmp <='z' || tmp >='0' && tmp <='9' || tmp =='-' || tmp=='.' || tmp=='_')){
continue;
}
//step 3
if(i>0 && answer[answer.length()-1] == '.' && tmp == '.'){
continue;
}
answer.push_back(tmp);
}
//step 4
if(answer[0]=='.') answer.erase(0,1);
if(answer[answer.length()-1]=='.') answer.erase(answer.length()-1,1);
//step 5
if(answer.length() == 0){
answer.push_back('a');
}
//step 6
if(answer.length() > 15){
answer.resize(15);
}
if(answer[answer.length()-1]=='.') answer.erase(answer.length()-1,1);
//step 7
if(answer.length()<3){
answer.resize(3, answer[answer.length()-1]);
}
return answer;
}
'알고리즘 (Algorihtm) > 카카오' 카테고리의 다른 글
2021 KAKAO Blind - 5. 광고 삽입 (0) | 2021.12.10 |
---|---|
2021 KAKAO Blind - 7. 매출 하락 최소화 (2) | 2021.08.25 |
2021 KAKAO Blind - 4. 합승 택시 요금 (1) | 2021.08.25 |
2021 KAKAO Blind - 3. 순위 검색 (0) | 2021.08.19 |
2021 KAKAO Blind - 2. 메뉴 리뉴얼 (0) | 2021.08.12 |