문제 설명
네오와 프로도가 숫자놀이를 하고 있습니다. 네오가 프로도에게 숫자를 건넬 때 일부 자릿수를 영단어로 바꾼 카드를 건네주면 프로도는 원래 숫자를 찾는 게임입니다.다음은 숫자의 일부 자릿수를 영단어로 바꾸는 예시입니다.
1478 → "one4seveneight"
234567 → "23four5six7"
10203 → "1zerotwozero3"
이렇게 숫자의 일부 자릿수가 영단어로 바뀌어졌거나, 혹은 바뀌지 않고 그대로인 문자열 s가 매개변수로 주어집니다. s가 의미하는 원래 숫자를 return 하도록 solution 함수를 완성해주세요.참고로 각 숫자에 대응되는 영단어는 다음 표와 같습니다.
숫자 / 영단어
0 zero
1 one
2 two
3 three
4 four
5 five
6 six
7 seven
8 eight
9 nine
제한 조건
1 ≤ s의 길이 ≤ 50
s가 "zero" 또는 "0"으로 시작하는 경우는 주어지지 않습니다.
return 값이 1 이상 2,000,000,000 이하의 정수가 되는 올바른 입력만 s로 주어집니다
입출력 예
s / result
"one4seveneight" 1478
"23four5six7" 234567
"2three45sixseven" 234567
"123" 123
입출력 예 설명
입출력 예 #1문제 예시와 같습니다.
입출력 예 #2문제 예시와 같습니다.
입출력 예 #3"three"는 3, "six"는 6, "seven"은 7에 대응되기 때문에 정답은 입출력 예 #2와 같은 234567이 됩니다.
입출력 예 #2와 #3과 같이 같은 정답을 가리키는 문자열이 여러 가지가 나올 수 있습니다.
입출력 예 #4s에는 영단어로 바뀐 부분이 없습니다.
문제풀이
const numbers = ["zero","one","two","three","four","five","six","seven","eight","nine"]; function solution(s) { for(let i = 0; i <numbers.length; i++){ console.log(i , numbers[i]) s = s.replace(numbers[i] , i) } return Number(s) }
접근방법
1. 전체문자열에서 zero라는 문자열을 찾아서
있다면 zero라는 문자열을 0으로 바꿔주도록 한다.
0ne이 있다면 1로 , two가 있다면 2로 ~ 9까지 반복한다.
2. 그러기 위해서 영어단어들을 하나로 그룹핑을 해본다.
3. 반복문을 돌려서 해당 문자열의 인덱스값을 확인해본다.for(let i = 0; i <numbers.length; i++){ console.log(i , numbers[i]) }
- 문자열을 변경해준다. 문자열은 일종의 변수와는 달리 0번째를 a로 바꾸겠다 이런 것이 불가능하다. 따라서 메소드를 활용해야함. replace()!
- 전체문자열 s를 찍어보면 찾은 해당 문자열을 숫자로 바꿔준다.
그러나 replace는 문자열안에서 가장 먼저 찾은 문자열 하나만 바꾸는 특성을 가지기 때문에, 중복되는 문자열이 있어도 뒤에 있는 문자열에는 메소드가 적용되지 않는다.
따라서 while문으로 한번더 이중반복문을 돌려서 찾아낸뒤 바꿀 수 있도록 해준다.const numbers = ["zero","one","two","three","four","five","six","seven","eight","nine"]; function solution(s) { for(let i = 0; i <numbers.length; i++){ while(s.includes ( numbers[i] )) { s = s.replace(numbers[i] , i) } } return Number(s) }
이걸 대체할 수 있는 메소드가 따로 있음!
replaceAll()
메소드활용
const numbers = ["zero","one","two","three","four","five","six","seven","eight","nine"]; function solution(s) { for(let i = 0; i <numbers.length; i++){ s = s.replaceAll( numbers[i] , i ) } return Number(s) }
const numbers = ["zero","one","two","three","four","five","six","seven","eight","nine"]; function solution(s) { for(let i = 0; i <numbers.length; i++){ s = s.split(numbers[i]).join(i) } return Number(s) }
-> replaceAll이 없을때는 split과 join을 사용한 방법도 있었음.
정규표현식을 사용한 방법function solution(s) { s = s.replaceAll(/zero/g,0) s = s.replaceAll(/one/g,1) s = s.replaceAll(/two/g,2) s = s.replaceAll(/three/g,3) s = s.replaceAll(/four/g,4) s = s.replaceAll(/five/g,5) s = s.replaceAll(/six/g,6) s = s.replaceAll(/seven/g,7) s = s.replaceAll(/eight/g,8) s = s.replaceAll(/nine/g,9) return Number(s) }
replaceAll에서는 정규표현식을 직접적으로 사용이 불가하다.(타입에러남)
따라서 정규표현식 안에서 제공하는 기능을 사용
g(global)이라는 옵션을 사용!
리팩토링const numbers = ["zero","one","two","three","four","five","six","seven","eight","nine"]; function solution(s) { for(let i = 0; i< numbers.length; i++){ const regExp = new RegExp(numbers[i], "g") s = s.replace(regExp,i) } return Number(s) }
동적으로 정규표현식 사용하기!
regExp가 변수가 할당된 정규표현식을 완성시키는 데 도와줌