[프로그래머스] 숫자 문자열과 영단어 - Javascript

bang·2021년 7월 31일
0

문제설명

네오와 프로도가 숫자놀이를 하고 있습니다. 네오가 프로도에게 숫자를 건넬 때 일부 자릿수를 영단어로 바꾼 카드를 건네주면 프로도는 원래 숫자를 찾는 게임입니다.

다음은 숫자의 일부 자릿수를 영단어로 바꾸는 예시입니다.

  • 1478 → "one4seveneight"
  • 234567 → "23four5six7"
  • 10203 → "1zerotwozero3"

이렇게 숫자의 일부 자릿수가 영단어로 바뀌어졌거나, 혹은 바뀌지 않고 그대로인 문자열 s가 매개변수로 주어집니다. s가 의미하는 원래 숫자를 return 하도록 solution 함수를 완성해주세요.

참고로 각 숫자에 대응되는 영단어는 다음 표와 같습니다.

입출력 예

코드

function solution(s) {
    let numbers = ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine'];// 1
    let arr = [...s];//2
    let alphabet = [];//3

    if(!isNaN(s)) return Number(s);
    for (let i = 0; i < arr.length; i++) {
        if (isNaN(arr[i])) {//4
            alphabet.push(arr[i]);//5
        } else {//6
            continue;
        }
        let str = alphabet.join('')//7
        for (let j = 0; j < numbers.length; j++) {//8
            if (str === numbers[j]) {//9
                s = s.replace(str, j);//10
                alphabet = [];//11
            }
        }
    }
    return +s;
}

문제풀이

  1. 배열의 인덱스를 이용해서 문자와 숫자를 배치

    인덱스 0 -> "zero"

  2. 문자열 s를 spread문법을 사용해 배열 arr로 만들기
    ['o','n','e','4','s','e','v','e','n','e','i','g','h','t']
  3. 빈 배열인 alphabet 만들기(스택 구조로 사용)
  4. 배열 arr을 반복문을 돌리는데 한개씩 숫자인지 아닌 지 검사
  5. 숫자가 아니면 배열 alphabet에 담기
  6. 숫자이면 건너뛰기
  7. 배열 alphabet을 문자열 str으로 합침
    ['o','n'] -> 'on'
  8. 배열 numbers를 이용해 반복문을 돌려서
  9. 문자열 str이 배열 numbers의 값과 일치하는 지 검사 후
  10. 같으면 문자열 s의 문자열 str가 같은 부분을 배열 j의 인덱스를 이용해서 숫자로 변환
  11. 배열 alphabet을 빈 배열로 초기화

회고

처음에 문자열 s를 spread 문법을 사용해 배열 arr로 만들지 않고 그냥 사용했는데

for (let i = 0; i < s.length; i++)

이런 식으로 하니까 하나씩 검사하다가 몇개를 건너뛰는 문제가 발생했다.
이유는

 s = s.replace(str, j);

문자열 s에 replace함수로 바뀐 s를 다시 대입하니까 문자열의 길이가 달라져서
인덱스에도 변화가 생겨 몇 개를 건너뛰었다.

one4seveneight ->14seveneight

처음 4는 3번째였지만 one이 1로 바뀌면서 4는 첫번 째 인덱스가 되고 3번째 인덱스는
e가 되어 중간에 4,s를 건너뛰는 문제가 발생했다.

이를 해결하기위해 별도의 배열 arr을 만들어 생략되는 거 없이 전체가 숫자인지 알파벳인지 검사할 수 있게 하였다.

다른 사람 풀이

function solution(s) {
    let numbers = ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"];
    var answer = s;

    for(let i=0; i< numbers.length; i++) {
        let arr = answer.split(numbers[i]);
        answer = arr.join(i);
    }

    return Number(answer);
}

다른 사람의 풀이지만 너무 간결하게 잘해서 가져와봤다.
split으로 문자열 사이의 영어를 나누고 나뉜 배열을 join()을 배열의 인덱스를 사용해 다시 숫자로 합치는 것이다.

[' ',4seveneight] -> join(1) ->"14seveneight"
['14', 'eight'] -> join(7) -> "147eight"
[147', ' '] -> join(8) -> "1478"

0개의 댓글