개발하는 kim-hasa

[c++][프로그래머스] 신규 아이디 추천 본문

Algorithm/Programmers(c++)

[c++][프로그래머스] 신규 아이디 추천

kim-hasa 2021. 7. 28. 19:33

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

 

코딩테스트 연습 - 신규 아이디 추천

카카오에 입사한 신입 개발자 네오는 "카카오계정개발팀"에 배치되어, 카카오 서비스에 가입하는 유저들의 아이디를 생성하는 업무를 담당하게 되었습니다. "네오"에게 주어진 첫 업무는 새로

programmers.co.kr

신규로 아이디를 추천해주는 프로그램 입니다.

 

1단계 new_id의 모든 대문자를 대응되는 소문자로 치환합니다.

2단계 new_id에서 알파벳 소문자, 숫자, 빼기(-), 밑줄(_), 마침표(.)를 제외한 모든 문자를 제거합니다.

3단계 new_id에서 마침표(.)가 2번 이상 연속된 부분을 하나의 마침표(.)로 치환합니다.

4단계 new_id에서 마침표(.)가 처음이나 끝에 위치한다면 제거합니다.

5단계 new_id가 빈 문자열이라면, new_id에 "a"를 대입합니다.

6단계 new_id의 길이가 16자 이상이면, new_id의 첫 15개의 문자를 제외한 나머지 문자들을 모두 제거합니다.

        만약 제거 후 마침표(.)가 new_id의 끝에 위치한다면 끝에 위치한 마침표(.) 문자를 제거합니다.

7단계 new_id의 길이가 2자 이하라면, new_id의 마지막 문자를 new_id의 길이가 3이 될 때까지 반복해서 끝에 붙입니다.

 

가장 먼저 transform 알고리즘을 통해 소문자로 변환합니다. (1단계)

 

그리고 answer 뒤에 문자를 하나씩 붙여갑니다. 이때, 영어나 숫자, - 와 _, 그리고 . 인 경우에는 그냥 추가합니다.(2단계)

 

추가 중에 dotcount를 이용해서 .이 연속으로 나오는 경우에는 추가하지 않습니다. (3단계)

 

마침표가 처음이면 제거합니다. (4단계)

이 때, 마지막 마침표를 제거하지 않는 이유는 15자 이상인 경우에 한번 자르고 그 아래에서 한 번 더 제거하기 때문에 중복이어서 해주지 않았습니다.

 

길이가 0이라면 a를 추가합니다. (5단계)

 

길이가 16자 이상이라면, 15자만 남기고 제거합니다. (6단계) 그 후 마지막 마침표를 제거합니다.

 

마지막으로 2자 이하라면 길이가 3이 될때까지 반복합니다.

 

문자열 substr, erase, back 등과 transform 알고리즘을 처음으로 적용해본 문제였습니다. 그동안은 어렵게 문제를 해결했었는데 좋은 도구들을 익힌 것 같아서 뿌듯합니다.

#include <string>
#include <vector>
#include <algorithm>

using namespace std;

string solution(string new_id) {
    string answer = "";
    string id = new_id;
    transform(id.begin(), id.end(), id.begin(), ::tolower); // 소문자 변환, 1단계
    int dotCount = 0;   //  .을 체크하는 카운트
    
    for(int i=0; i<id.length(); i++)
    {
        char c = id[i]; // 한 단어씩 계산
        
        if( c >= 97 && c <= 122)    // 알파벳인 경우
        {
            answer += c;
            dotCount = 0;
        }
        else if(c == '0' || c == '1' || c == '2' || c == '3' || c == '4' || c == '5' || c == '6' || c == '7' || c == '8' || c == '9')   // 숫자인 경우
        {
            answer += c;
            dotCount = 0;
        }
        else if(c == '-' || c == '_')   // - 또는 _ 인 경우
        {
            answer += c;
            dotCount = 0;
        }
        else if(c == '.' && dotCount == 0)  // . 이 선행되지 않고 들어가는 경우
        {
            answer += c;
            dotCount = 1;
        }
    }
    
    if(answer[0] == '.')    // 처음이 . 인 경우
    {
        answer.erase(0,1);
    }
    
    if(answer.length() == 0)    // 길이가 0인 경우
    {
        answer += 'a';
    }
    
    if(answer.length() > 15)    // 길이가 16자 이상인 경우
    {
        answer = answer.substr(0,15);
    }
    
    if(answer.back() == '.')    // 맨 뒤 자리가 . 인 경우
    {
        answer.erase(answer.end()-1);
    }
    
    while(answer.length() < 3)  // 2자 이하인 경우
    {
        answer += answer.back();
    }
    
    return answer;
}

※ 코드가 지저분할 수 있습니다.