오늘 해결한 두번째 문제는 프로그래머스 신규 아이디 추천 이다! 작년 카카오 공채 1차 1번 문제였던걸로 기억하는 문제,, 물론 떨어짐~ 사실 어제 푼 문제인데 괜히 이상한 방식으로 접근해서 오늘에서야 그냥 일반적인 방식으로 해결할 수 있었다..왜그랬을까? ㅋ
카카오에 입사한 신입 개발자 네오는 "카카오계정개발팀"에 배치되어, 카카오 서비스에 가입하는 유저들의 아이디를 생성하는 업무를 담당하게 되었습니다. "네오"에게 주어진 첫 업무는 새로 가입하는 유저들이 카카오 아이디 규칙에 맞지 않는 아이디를 입력했을 때, 입력된 아이디와 유사하면서 규칙에 맞는 아이디를 추천해주는 프로그램을 개발하는 것입니다.
다음은 카카오 아이디의 규칙입니다.
"네오"는 다음과 같이 7단계의 순차적인 처리 과정을 통해 신규 유저가 입력한 아이디가 카카오 아이디 규칙에 맞는 지 검사하고 규칙에 맞지 않은 경우 규칙에 맞는 새로운 아이디를 추천해 주려고 합니다.
신규 유저가 입력한 아이디가 new_id 라고 한다면,
신규 유저가 입력한 아이디를 나타내는 new_id가 매개변수로 주어질 때, "네오"가 설계한 7단계의 처리 과정을 거친 후의 추천 아이디를 return 하도록 solution 함수를 완성해 주세요.
no | new_id | result |
---|---|---|
예1 | "...!@BaT#*..y.abcdefghijklm" | "bat.y.abcdefghi" |
예2 | "z-+.^." | "z--" |
예3 | "=.=" | "aaa" |
예4 | "123_.def" | "123_.def" |
예5 | "abcdefghijklmn.p" | "abcdefghijklmn" |
문제 자체에 적합한 아이디를 만들어가는 순서가 나와있기 때문에 주어진 조건에 맞게 해결하기만 하면 되는 문제이다.
나는 처음에 단계별로 문자를 지우고 옮기고 하는 과정이 뭔가 메모리나 시간적으로 낭비일 것 같아서 주어지는 문자열 new_id
를 그대로 두고 각 문자가 살아남았는지 아닌지를 단계별로 체크한 후에 마지막에 한번에 싹 가져가서 반환해야지~! 라는 패기로운 마음으로 코드를 짰다,,
ㅎㅎ,, 뭐 나쁜 시도는 아니었지만 총 26개의 테스트 케이스 중 20번 한가지만 계속 실패가 떴다. 올라와 있는 질문도 보고 구글링 해 봐도 나와 같은 사람은 한명..? 밖에 없었다. 20번에서 걸리는 사람들은 대부분 다른 케이스에서도 함께 걸려서 그 반례로 해결하면서 20번까지 커버가 되는 것 같았는데 나는 왠만한 반례는 다 넣어봐도 정상적으로 돌아가고 20번만을 확인하는 반례를 결국 찾지 못했다.
그래서 그냥 오늘 string.replace()
을 사용하여 좀 더 일반적인 방법으로 접근해보았다. 각 조건에 적합하지 않은 문자가 있으면 string.replace(i, 1, "")
를 사용해 삭제하고 마지막 6,7 단계에선 길이를 확인해서 채워주거나 지워주면 된다.
정규식을 사용해서 2,3 번에 적용할 수 있을 것 같은데 정규식은 사실 좀 생소하지만 공부해서 한번 풀어봐야겠다! 역시나 오늘도 허무한 나의 알골 시간~~ ^^
#include <string>
#include <vector>
#include <iostream>
using namespace std;
string solution(string new_id) {
string answer = "";
int len = new_id.size();
// 1. 소문자 치환
for (int i = 0; i < len; ++i) {
if (new_id[i]>= 'A' && new_id[i] <= 'Z'){
new_id[i] = new_id[i] + 32;
}
}
// 2. 가능하지 않은 문자 제거
for (int i = 0; i < len; ++i) {
if (new_id[i] == 45 || new_id[i] == 46 || (new_id[i] >=48 && new_id[i] <=57) || new_id[i] == 95 ||
(new_id[i] >= 97 && new_id[i] <= 122)){
continue;
}else{
new_id.replace(i, 1, "");
len--;
i--;
}
}
// 3. 연속 마침표 하나로
for (int i = 0; i < len-1; ++i) {
if (new_id[i] == '.'){
int j = i+1;
while (new_id[j]=='.'){
new_id.replace(j,1,"");
len--;
}
}
}
// 4. 처음과 끝에 마침표가 있으면 제거
if(new_id[0] == '.'){
new_id.replace(0,1,"");
len--;
}
if (new_id[len-1] == '.'){
new_id.replace(len-1,1,"");
len--;
}
// 5. 비어있으면 "a" 대입
if (len == 0) {
new_id = "a";
len = 1;
}
// 6. 길이가 16 이상이면 15까지만
if (len >= 16){
while (len > 15){
new_id.replace(len-1,1,"");
len--;
}
if (new_id[len-1] == '.'){
new_id.replace(len-1,1,"");
len--;
}
}
// 7. 길이가 2 이하면 마지막 문자를 반복
if (len<=2){
char last = new_id[len-1];
while (len <3){
new_id += last;
len++;
}
}
return new_id;
}