안녕하세요:) 민쯔입니다.
프로그래머스 코딩 테스트 연습문제 "신규 아이디 추천" 문제 해결방안에 대해 설명하겠습니다.
프로그래머스 코딩 테스트 연습문제를 풀다 보면 터득하는 게 있는데요.
문제와 제한사항만 잘 읽으시면 반은 해결한 거라고 생각합니다.
"신규 아이디 추천"문제의 키 포인트는
문제설명
- new_id의 모든 대문자를 대응되는 소문자로 치환합니다.
- new_id에서 알파벳 소문자, 숫자, 빼기(-), 밑줄(_), 마침표(.)를 제외한 모든 문자를 제거합니다.
- new_id에서 마침표(.)가 2번 이상 연속된 부분을 하나의 마침표(.)로 치환합니다.
- new_id에서 마침표(.)가 처음이나 끝에 위치한다면 제거합니다.
- new_id가 빈 문자열이라면, new_id에 "a"를 대입합니다.
- new_id의 길이가 16자 이상이면, new_id의 첫 15개의 문자를 제외한 나머지 문자들을 모두 제거합니다. 만약 제거 후 마침표(.)가 new_id의 끝에 위치한다면 끝에 위치한 마침표(.) 문자를 제거합니다.
- new_id의 길이가 2자 이하라면, new_id의 마지막 문자를 new_id의 길이가 3이 될 때까지 반복해서 끝에 붙입니다.
제한사항
new_id에 나타날 수 있는 특수문자는 -_.~!@#$%^&*()=+[{]}:?,<>/ 로 한정됩니다.
이 두 가지입니다.
저는 문제 설명에 7단계에 대한 설명글을 쭉 보면서 느낀 게
"이건 무조건 replace에 정규식으로 풀어야겠다."
라는 생각이 들었습니다.
먼저 해결방안을 봅시다.
function solution(new_id) {
// 1단계
new_id = new_id.toLowerCase();
// 2단계
new_id = new_id.replace(/[^a-z0-9|\-|_|.]/g,'');
// 3단계
new_id = new_id.replace(/\.+/g,'.');
// 4단계
new_id = new_id.replace(/^\.|\.$/g,'');
// 5단계
if(new_id.length === 0) new_id = new_id + 'a';
// 6단계
if(new_id.length > 15) new_id = new_id.slice(0, 15);
new_id = new_id.replace(/\.$/g,'');
// 7단계
let lastChar = new_id.charAt(new_id.length-1);
for(let i = new_id.length; i<3; i++) new_id = new_id + lastChar;
return new_id;
}
1단계
toLowerCase()를 사용하여 대문자를 소문자로 고쳤습니다.
2단계
"알파벳 소문자, 숫자, 빼기(-), 밑줄(_), 마침표(.)를 제외한 모든 문자를 제거"라는 문구가 있습니다.
말 그대로 정규식으로 표현하면 됩니다.
- 알파벳 소문자(a~z) : a-z
- 숫자(0~9) : 0-9
- 빼기(-), 밑줄(_), 마침표(.) : |\-|_|.
- | : 또는과 의미가 비슷합니다.
- \ : 특정한 특수문자는 작동이 안 될 때가 있어서 안될 경우 \를 사용하시면 잘 작동됩니다.
- [^] : "^"는 부정의 의미입니다.
- g : 전체 매칭
위에 내용을 다 합쳐서 쓰면
/[^a-z0-9|\-|_|.]/g 이렇게 됩니다.
더 쉽게 쓰면 /[^\w|\-|_|.]/g 이렇게 쓰기도 하는데
- \w : a~z, A~Z, 0~9
저는 알아보기도 좋고 문구 내용에 보다 정확하다고 생각해서 a-z0-9 썼습니다.
정규식을 쓸 때 바로 쓰기에는 어려워서ㅜㅜ 이 사이트에서 확인하면서 작성했습니다!!
RegExr: Learn, Build, & Test RegEx
정규식 쓸 때. 글 쓰면 좀 이상해서. 앞에는 \를 붙였습니다. \.
3단계
"마침표(.)가 2번 이상 연속된 부분을 하나의 마침표(.)로 치환"에서는 +를 사용해 줬습니다.
- + : 1회 이상 반복
- \.+ : "."이 1회 이상 반복되면
/\.+/g 작성했습니다.
4단계
"마침표(.)가 처음이나 끝에 위치한다면 제거"에서 ^, $를 사용했습니다.
- ^ : 처음
- $ : 끝
- ^\. : 첫 글자가 "."인 거 표시
- \.$ : 마지막 글자가 "."인 거 표시
/^\.|\.$/g 작성했습니다.
5단계
"빈 문자열이라면, new_id에 "a"를 대입"
- 빈 문자열이라면 : if(new_id.length === 0)
- new_id에 "a"를 대입 : new_id = new_id + 'a';
if(new_id.length === 0){new_id = new_id + 'a';}
6단계
"new_id의 길이가 16자 이상이면, new_id의 첫 15개의 문자를 제외한 나머지 문자들을 모두 제거"
- new_id의 길이가 16자 이상 : if(new_id.length > 15)
- new_id의 첫 15개의 문자를 제외한 나머지 문자들을 모두 제거 : new_id.slice(0, 15);
- new_id.slice(0, 15); : new_id 문자열 0번부터 14번 부분만 리턴
-> 15개 문자까지이기 때문에 0~14(15개)까지만 허용
if(new_id.length > 15){new_id = new_id.slice(0, 15);}
"제거 후 마침표(.)가 new_id의 끝에 위치한다면 끝에 위치한 마침표(.) 문자를 제거"
new_id = new_id.replace(/\.$/g, '');
7단계
"길이가 2자 이하라면, 마지막 문자를 new_id의 길이가 3이 될 때까지 반복해서 끝에 붙입니다."
- new_id의 마지막 문자 : new_id.charAt(new_id.length-1) 를 lastChar에 담아 줬습니다.
- charAt() : 문자열에서 특정 인덱스에 위치하는 단일 문자 반환
-> 여기서 첫 번째 문자의 순번은 0, 마지막 문자 순번은 stringName.length - 1입니다.
- new_id의 길이 : new_id.length
- 길이가 2자 이하라면, new_id의 길이가 3이 될 때까지 반복 : for(let i = new_id.length; i<3; i++)
- for(let i = new_id.length; i<3; i++) :
- let i에 new_id.length을 대입하여 new_id.length(즉 new_id의 길이) 2 이하인 것만 반복하게 했습니다.
- 마지막 문자를 new_id 끝에 붙입니다. : new_id = new_id + lastChar;
- 마지막 문자를 new_id의 길이가 3이 될 때까지 반복해서 끝에 붙입니다. :
for(let i = new_id.length; i<3; i++){new_id = new_id + lastChar;}
let lastChar = new_id.charAt(new_id.length-1);
for(let i = new_id.length; i<3; i++){new_id = new_id + lastChar;}
'코딩 > 프로그래머스 코딩테스트' 카테고리의 다른 글
[프로그래머스] 약수의 개수와 덧셈 (0) | 2021.10.14 |
---|---|
[프로그래머스] 예산 (0) | 2021.10.06 |
[프로그래머스] K번째수 (0) | 2021.10.02 |
[프로그래머스] 내적 (0) | 2021.09.24 |
[프로그래머스] 없는 숫자 더하기 (0) | 2021.09.17 |