[프로그래머스/C++]Lv.1 - 신규 아이디 추천

YH J·2023년 5월 21일
0

프로그래머스

목록 보기
90/168

문제 링크

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

내 풀이

단순하게 풀었다. 문제에 적힌 순서대로 해결하였다. 16자 이상이면 첫 15자만 살리고 다 제거한 뒤 끝이 마침표 일 수도 있으니 한번 더 제거해준다.

내 코드

#include <string>
#include <vector>
using namespace std;

void elimdot(string& inString)
{
    if(inString.front() == '.')
        inString.erase(inString.begin());
    if(inString.back() == '.')
        inString.erase(inString.end() - 1);
}

string solution(string new_id) {
    string answer = "";
    
    // 1. 대문자를 소문자로
    for(int i = 0; i < new_id.size(); i++)
        new_id[i] = tolower(new_id[i]);
    // 2. -,_,. 제외한 모든 특수문자 제거
    for(int i = 0; i < new_id.size();)
    {
        if((new_id[i] >= 'a' && new_id[i] <= 'z') || new_id[i] == '-' || new_id[i] == '_' || new_id[i] == '.' || isdigit(new_id[i]))
        {
            i++;
            continue;
        }
        new_id.erase(new_id.begin() + i);
    }
    // 3. .이 2번이상인 부분 1개로 치환
    for(int i = 1; i < new_id.size(); i++)
    {
        if(new_id[i] == '.' && new_id[i - 1] == '.')
        {
            new_id.erase(new_id.begin() + i);
            i--;
        }
    }
    // 4. .이 처음이나 끝이면 제거
    elimdot(new_id);
    // 5. 빈 문자열이면 a대입
    if(new_id.size() == 0)
        new_id += 'a';
    // 6. 16자 이상이면 첫 15자만 살리고 다 제거
    if(new_id.size() >= 16)
        new_id.erase(new_id.begin() + 15,new_id.end());
    elimdot(new_id);
    // 7. 2자 이하면 마지막 문자를 3이 될 때 까지 
    while(new_id.size() < 3)
        new_id += new_id.back();
    answer = new_id;
    
    return answer;
}

다른 사람의 풀이

#include <bits/stdc++.h>
using namespace std;

string solution(string new_id) {
    for (char& ch : new_id) if ('A' <= ch && ch <= 'Z') ch |= 32;

    string ret;
    for (char& ch: new_id) {
        if ('a' <= ch && ch <= 'z' ||
            '0' <= ch && ch <= '9' ||
            strchr("-_.", ch)) ret += ch;
    }

    new_id = ret;
    ret.clear();
    for (char& ch: new_id) {
        if (!ret.empty() && ret.back() == '.' && ch == '.') continue;
        ret += ch;
    }

    if (ret.front() == '.') ret.erase(ret.begin());
    if (ret.back() == '.') ret.pop_back();

    if (ret.empty()) ret = "a";
    if (ret.size() >= 16) ret = ret.substr(0, 15);
    if (ret.back() == '.') ret.pop_back();
    while (ret.size() <= 2) ret += ret.back();

    return ret;
}

다른 사람의 풀이 해석

최적화에도 많이 신경 쓴 코드다.
1. 대문자를 소문자로 바꾸는데 or연산으로 32를 더했다. (아스키 코드상 대문자에서 소문자로 변환하려면 32를 더하면 된다.
2. string 변수(ret)를 하나 만든 뒤 소문자 알파벳, 숫자, _, -, .에 해당하는 글자들만 ret에 담고 new_id에 ret을 넣어준 뒤 ret을 초기화한다.
3. new_id를 한글자 한글자 검사하면서 '.'의 중복을 제거해준다.
4. 맨앞이나 맨 뒤에있는 '.'을 제거해준다.
5. ret이 비어있을 경우 a를 넣어준다.
6. 16글자 이상인 경우 substr로 0부터 15글자까지만 뽑아준다. 이 과정에서 15번째 글자가 '.'인 경우 제거해준다.
7. 3글자 미만인 경우 마지막글자를 더해준다.

  • strchr(char* str,int c) str문자열 내에 c가 있는지 찾아주는 함수 c는 int이지만 아스키코드
profile
게임 개발자 지망생

0개의 댓글