문제 설명
프로그래머스 모바일은 개인정보 보호를 위해 고지서를 보낼 때 고객들의 전화번호의 일부를 가립니다. 전화번호가 문자열 phone_number로 주어졌을 때, 전화번호의 뒷 4자리를 제외한 나머지 숫자를 전부 *으로 가린 문자열을 리턴하는 함수, solution을 완성해주세요.
제한 조건
- phone_number는 길이 4 이상, 20이하인 문자열입니다.
입출력 예
phone_number | return |
"01033334444" | "*******4444" |
"027778888" | "*****8888" |
내풀이
function solution(str) {
let backDigitNumber = str.slice(-4);
let hidden = '*'.repeat(str.length - 4);
return hidden + backDigitNumber;
}
문제 해결 과정
전화번호의 뒷 자리를 제외한 나머지 숫자를 * 로 가린 문자열로 반환하는 문제로 문제의 접근 방식은 우선 아래와 같이 요구사항으로 분류했다.
1. 핸드폰 번호 뒷 4자리 숫자를 변수에 저장한다.
2. 나머지 숫자에 대해 전부 * 으로 가린 문자열을 반복한다.
3. 그 결과에 저장했던 4자리 숫자를 담은 변수와 2번째의 * 문자열을 합쳐서 결과로 반환한다.
그 결과가 위의 풀이 결과로, 인자로 받은 문자열을 slice 메서드로 뒤의 4번째 숫자 값을 backDigitNumber에 저장하고, 나머지 숫자들을 repeat 메서드를 이용해서 hidden 변수에 저장한 후 그 더한 결과를 반환 값으로 전달해서 문제를 해결했다.
다른 방법
function solution(phone_number) {
let answer = '';
let phoneNumberLength = phone_number.length - 1;
for(let i = 0; i <= phoneNumberLength; i+=1) {
if(i >= phoneNumberLength - 3) {
answer += phone_number[i];
continue;
}
answer += '*';
}
return answer;
}
메서드가 아닌 반복문을 이용한 방법으로, string은 immutable한 데이터 타입이기 때문에 직접 값을 변경할 수 없으므로 값을 담을 빈 문자열을 선언하고, 반복문을 통해 핸드폰 번호의 길이만큼 순회하면서 i의 인덱스가 마지막 4개의 숫자에 도달했을 때를 조건으로 해서 그때의 phone_number의 인덱스 값을 answer에 저장하고, 그렇지 않다면 answer 변수에 *을 전달하여 반복문이 종료됐을 때, 그 문자열에 핸드폰 번호를 가린 결과가 문자열로 담기도록 해서 결과를 반환하는 방법으로 구현해봤다.
다른 사람 풀이
function hide_numbers(s) {
return s.replace(/\d(?=\d{4})/g, "*");
}
정규 표현식을 이용한 방법은 알고 있었지만 막상 문제를 풀 때, 전혀 생각하지 못했다. 그러한 관점에서 정말 다양한 풀이가 있다는 것을 알게 됐다. 이 방식은 replace 메소드 때문에 실행속도는 repeat + slice를 사용한 방법보다 3배 느리게 동작하지만, 사용하는 방법이 익숙하다면 더 복잡한 코드를 보다 간결하게 표현할 수 있다는 장점이 있다.
replace 메소드
기존 String 객체를 바꾸지 않고, 새로운 문자열을 리턴하게 된다.
구문
var newStr = str.replace(regExp|sbustr, newSubStre|function)
매개변수
regexp (pattern), substr (pattern), newSubStr (replacement), fucntion (replacement) 이 존재하며, 자세한 설명은 아래의 MDN 사이트에서 확인해볼 수 있다. 매개변수의 교체될 인자가 무엇인지에 따라서 사용할 수 있는 특수 패턴도 존재한다.
반환값 : 어떤 패턴에 일치하는 일부 또는 모든 부분이 교체된 새로운 문자열
[ MDN - replace ] https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/String/replace
String.prototype.replace() - JavaScript | MDN
replace() 메서드는 어떤 패턴에 일치하는 일부 또는 모든 부분이 교체된 새로운 문자열을 반환합니다. 그 패턴은 문자열이나 정규식(RegExp)이 될 수 있으며, 교체 문자열은 문자열이나 모든 매치
developer.mozilla.org
정규 표현식 풀이
\d : Digit , 즉 0부터 9까지의 숫자가 올 수 있음을 의미한다.
(?= ) : Poisitive Lookahead(긍정형 전방탐색), 괄호에서 작성한 패턴에 일치하는 영역이 존재하면 그 값이 제외되는 패턴으로 ' = ' 기호 뒤에 오는 문자가 일치하는 영역에서 제외된다.
{ } : Quantifier, 앞의 조건에 대해 지정된 수량과 일치하는 조건으로 현재 \d{4}라는 조건이므로 0부터 9까지의 4개의 숫자가 있어야 일치한다는 조건을 의미한다.
이 표현식을 모두 조합했을 때, 앞에서 0~9까지의 숫자가 오면서, 뒤에 4자리 숫자가 있는 경우 영역에서 제외된다. 따라서 그 전까지는 모두 true이기 때문에 앞의 자릿수는 replace가 되어 *이 붙게되고, 남은 숫자가 4개로 되는 순간, 그 앞의 숫자가 문자 * 로 치환되므로 더 이상 일치하는 패턴이 없어 함수가 종료되고, 그 결과를 출력하게 된다.
관련 문법에 관한 내용은 아래의 블로그와 사이트를 참조했다.
[ 정규 표현식 강좌 9편. 전후방탐색 ] https://blog.hexabrain.net/205
[ RegExr ] https://regexr.com/
정규 표현식(Regex) 강좌 9편. 전후방탐색(lookaround)
1. 전방 탐색(lookahead) 전방 탐색(lookahead)이란 작성한 패턴에 일치하는 영역이 존재하여도 그 값이 제외되어서 나오는 패턴입니다. 전방 탐색 기호는 ?= 이며, = 다음에 오는 문자가 일치하는 영역
blog.hexabrain.net
RegExr: Learn, Build, & Test RegEx
RegExr is an online tool to learn, build, & test Regular Expressions (RegEx / RegExp).
regexr.com
'Problem Solving > 프로그래머스' 카테고리의 다른 글
[ Lv. 2 ] 소수 찾기 - JavaScript (0) | 2022.06.25 |
---|---|
[ Lv. 1 ] 모의고사 - JavaScript (0) | 2022.06.25 |
[ Lv. 1 ] 최대공약수와 최소공배수 - JavaScript (0) | 2022.06.11 |
[ Lv. 1 ] 하샤드 수 - JavaScript (0) | 2022.06.10 |
[ Lv. 1 ] 직사각형 별 찍기 - JavaScript (0) | 2022.06.10 |