문제 설명
문자열 my_string이 매개변수로 주어집니다. my_string은 소문자, 대문자, 자연수로만 구성되어있습니다. my_string안의 자연수들의 합을 return하도록 solution 함수를 완성해주세요.
제한사항
- 1 ≤ my_string의 길이 ≤ 1,000
- 1 ≤ my_string 안의 자연수 ≤ 1000
- 연속된 수는 하나의 숫자로 간주합니다.
- 000123과 같이 0이 선행하는 경우는 없습니다.
- 문자열에 자연수가 없는 경우 0을 return 해주세요.
입출력 예
my_string | result |
"aAb1B2cC34oOp" | 37 |
"1a2b3c4d123Z" | 133 |
처음에는 단순하게 정규표현식을 사용해서 영어만 filter 메소드를 통해 제거하고 reduce메소드를 통해 합을 return 할 생각을 했지만
34같은 2자리 이상 숫자들이 함정 처럼 숨어있어서 이 방법을 포기하고
Stack을 이용한 풀이 방식을 적용해봤다.
Lv0 문제이니 만큼 논리는 단순한다.
1) stack = '' ; 을 선언하고
2) my_string을 순회해서 처음 숫자가 나오면 stack에 그 숫자가 끝날때까지 계속 더하는 것이다.
3) 그러다 숫자가 끝나고 알파벳이 오면 지금까지의 stack을 빈 배열 numArr에 push하고
4) stack을 다시 ''로 선언한다.
그렇게 해서 나오게 된 코드는
function solution(my_string) {
let stack = '';
let numArr = [];
for(const el of my_string){
if(el.match(/[0-9]/g)){
stack+=el
}else{
stack === '' ? '': numArr.push(stack)
stack =''
}
};
if(stack !== '') numArr.push(stack);
return numArr.reduce((acc,index)=>acc+Number(index),0);
}
이후에 정규표현식을 복습하고 풀이의 방향을 바꿔 보았다.
모든 알파벳을 공백(" ")으로 대체하고 공백을 기준으로 split 메소드를 적용하면 깔끔하게 숫자들만 분리가 된다. 이후 이 숫자들만 reduce 해주면 된다.
그렇게 해서 나온 코드는
function solution(my_string) {
return my_string.replace(/[A-z]/g, " ").split(" ").reduce((acc,index) => acc+Number(index),0)
}
단, 숫자들은 아직 string으로 되어 있기때문에 Number() 메소드를 적용해서 숫자로 변환 후 합 했다.
map 메소드를 적용해 미리 숫자로 변경해도 된다.
다른 분들의 풀이 중 정규표현식을 적용한 풀이를 소개한다.
function solution(my_string) {
return my_string.split(/\D+/).reduce((acc, cur) => acc + Number(cur), 0);
}
/\D+/ 라는 표현식을 사용해 본적이 없는데, 직접 사용해 보니 첫번째 예시 "aAb1B2cC34oOp"에 my_string.split(/\D+/) 을 적용하면
["", "1", "2", "34", ""] 이런 결과를 반환한다. 숫자만을 정확하게 분리한다.
Number("")은 0으로 계산되기에 위와 동일한 방식으로 reduce 메소드를 적용하면 된다.
만약 이 문제를 정규표현식 없이 풀었다면, 꼭 정규표현식으로 다시 풀어보기를 추천한다. 코드가 간결해지고 이해하기 쉬워지고 빨라진다.
'Algorithm > 푼 문제' 카테고리의 다른 글
프로그래머스/Lv2/[1차] 캐시 (0) | 2023.04.10 |
---|---|
프로그래머스/Lv0/팩토리얼 (0) | 2023.04.03 |
프로그래머스/Lv0/안전지대 (0) | 2023.04.01 |
프로그래머스/Lv0/외계어 사전(출제 오류?) (0) | 2023.04.01 |
프로그레머스/Lv0/약수 구하기 (0) | 2023.03.31 |