1. 문제풀이
1) 문제 : 숫자 문자열과 영단어, 프로그래머스
네오와 프로도가 숫자놀이를 하고 있습니다. 네오가 프로도에게 숫자를 건넬 때 일부 자릿수를 영단어로 바꾼 카드를 건네주면 프로도는 원래 숫자를 찾는 게임입니다. 다음은 숫자의 일부 자릿수를 영단어로 바꾸는 예시입니다.
- 1478 → "one4seveneight"
- 234567 → "23four5six7"
- 10203 → "1zerotwozero3"
이렇게 숫자의 일부 자릿수가 영단어로 바뀌어졌거나, 혹은 바뀌지 않고 그대로인 문자열 s가 매개변수로 주어집니다. s가 의미하는 원래 숫자를 return 하도록 solution 함수를 완성해 주세요. 참고로 각 숫자에 대응되는 영단어는 다음 표와 같습니다.
제한사항
- 1 ≤ s의 길이 ≤ 50
- s가 "zero" 또는 "0"으로 시작하는 경우는 주어지지 않습니다.
- return 값이 1 이상 2,000,000,000 이하의 정수가 되는 올바른 입력만 s로 주어집니다.
입출력 예 설명
- "one4seveneight" 1478
- "23four5six7" 234567
2) 해석
- 숫자와 영단어가 섞인 문자열이 주어짐
- 영단어 문자열 => 숫자로 바꾸기
- 해당 문자가 숫자면 answer에 넣기
- str문자가 arr에 있는지 확인 > 있으면 해당 문자의 index로 치환
3) 풀이
const arr = ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"];
function solution(s) {
let answer = 0;
let str = ""; //문자 담기
for(let i=0; i<s.length; i++){
if(!isNaN(s[i])) answer += s[i]
else {
str += s[i];
let idx = arr.indexOf(str);
if(idx !== -1) {
answer += `${idx}`;
str = ""; //초기화
}
}
}
return Number(answer);
}
let answer = 0;
let str = ""; //문자 담기
우선 answer와 str 변수를 생성해 준다.
str에는 for문을 돌면서 문자를 넣어줄 것이다.
if(!isNaN(s[i])) answer += s[i]
그 후 i번째 문자가 숫자인지 비교한 후, 숫자라면 answer에 값을 넣어준다.
else {
str += s[i];
let idx = arr.indexOf(str);
if(idx !== -1) {
answer += `${idx}`;
str = ""; //초기화
}
}
숫자가 아니라면, 해당 문자를 str에 넣어주고 str이 배열에 있는지 체크해 준다.
배열에 있다면, 해당 값을 answer에 넣어주고 str을 초기화해준다.
처음에 answer += idx를 했더니 테스트 케이스에서 에러가 발생했다.
알고 봤더니, idx가 숫자이기 때문에 발생한 것이었다.
숫자를 더하면 값이 달라지기 때문에 백틱으로 string 처리를 해준 다음 더해주는 것으로 수정했다.
- 걸린 시간
2. 리팩토링
1) 수정
코드를 딱 봤을 때 너무 지저분하게 느껴졌다. 좀 깔끔하게 정리할 수 있을까 고민해 봤다.
function solution(s) {
const arr = ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"];
let answer = 0;
let str = "";
for(let char of s){
if(!isNaN(char)) answer += char
else {
str += char
let idx = arr.indexOf(str);
if(idx !== -1) {
answer += `${idx}`;
str = "";
}
}
}
return Number(answer);
}
우선 바깥에 작성했던 arr를 함수 안쪽에 작성해 줬다.
리액트에서 값이 변하지 않으면 바깥에 사용하는 게 버릇이 돼서 나도 모르게 바깥쪽에 작성했던 것 같다ㅠ
그리고 기존에 사용했던 for문을 for... of로 수정해 줬다.
어차피 s의 길이만큼 반복문을 돌려주는 거라 for문보다 for of가 더 보기 편한 것 같다.
2) 다른 방법
function solution(s) {
const arr = ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"];
// 각 영단어를 숫자로 변환하는 방식으로 s를 변환
arr.forEach((word, idx) => {
s = s.replaceAll(word, idx);
});
return Number(s);
}
다른 사람들 코드를 보니까 replace를 사용하더라.
이게 훨씬 깔끔한 거 같아서 치환하는 건 replace를 사용하는 게 좋은 것 같다.
시간 복잡도는 둘 다 O(n)이다.
3. 기타
1) isNaN
isNaN(value);
value가 숫자인지 아닌지 체크하는 메서드.
값이 숫자가 아닌 경우 true, 숫자인 경우 false를 반환한다.
해당 값이 숫자로 변환 가능 값인 경우에도 false를 반환한다.
*Number.isNaN : 값이 실제로 NaN일 때만 true를 반환.
2) replace
string.replace(searchValue, replaceValue)
ex)
const paragraph = "I think Ruth's dog is cuter than your dog!";
console.log(paragraph.replace("Ruth's", 'my'));
// Expected output: "I think my dog is cuter than your dog!"
패턴을 새로운 패턴으로 반환하는 메서드.
변수에서 searchValue 패턴을 찾아 replaceValue 패턴으로 수정해 준다.
호출된 문자열의 값은 수정하지 않고, 새로운 문자열을 반환한다.
문자열의 패턴은 한 번만 바뀐다.
string.replaceAll(searchValue, replaceValue);
ex)
const paragraph = "I think Ruth's dog is cuter than your dog!";
console.log(paragraph.replaceAll('dog', 'monkey'));
// Expected output: "I think Ruth's monkey is cuter than your monkey!"
만일 모든 일치하는 패턴을 바꾸고 싶다면, replaceAll을 사용하면 된다.
'Algorithm > 99클럽' 카테고리의 다른 글
[99클럽] 코딩테스트 스터디, 7일차 TIL - 비기너 (0) | 2024.11.04 |
---|---|
[99클럽] 코딩테스트 스터디, 6일차 TIL - 비기너 (1) | 2024.11.04 |
[99클럽] 코딩테스트 스터디, 5일차 "모스부호" TIL - 비기너 (feat. 백준에서 자바스크립트 사용하기) (0) | 2024.11.03 |
[99클럽] 코딩테스트 스터디, 3일차 TIL - 비기너 (0) | 2024.10.30 |
[99클럽] 코딩테스트 스터디, 2일차 TIL - 비기너 (0) | 2024.10.29 |