본문 바로가기
코테

프로그래머스 JavaScript - 숫자 문자열과 영단어

by 해룸 2024. 2. 22.

문제

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

 

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

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

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

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

  • 1 ≤ s의 길이 ≤ 50
  • s가 "zero" 또는 "0"으로 시작하는 경우는 주어지지 않습니다.
  • return 값이 1 이상 2,000,000,000 이하의 정수가 되는 올바른 입력만 s로 주어집니다.
s return
"one4seveneight" 1478
"23four5six7" 234567

 

문제풀이

function solution(s) {
    var answer = '';
  var arr = ["zero","one","two","three","four","five","six","seven","eight","nine"]
   
  for(let i=0;i<s.length;i++){
      if(!isNaN(parseInt(s[i]))){
          answer += s[i]
      }else{
          var word = s[i]
          
            for (let j = 0; j < arr.length; j++) {
                if (s.startsWith(arr[j], i)) {
                    answer += j;
                    i += arr[j].length - 1;  // 매칭된 단어의 길이만큼 인덱스 이동
                    break;
                }
            }
          
      }
  }
  
    return +answer;
}

for문을 이용해 숫자일 경우 바로 answer에 s[i]를 넣는다. 숫자가 아닐경우 다음 for문에 들어가게 된다.

만약 s의 i번째 문자가 arr[j]로 시작할 경우 answer에 j를 넣는다. 그리고 매칭된 단어의 길이만큼 인덱스를 이동해

중복으로 문자열을 겹치지 않게 한다.

 

startsWith()

const str = "To be, or not to be, that is the question.";

console.log(str.startsWith("To be")); // true
console.log(str.startsWith("not to be")); // false
console.log(str.startsWith("not to be", 10)); // true

 

문제를 풀며 겪은 오류

var arr = [{0: "zero"}, {1: "one"}, {2: "two"}, {3: "three"}, {4: "four"}, {5: "five"}, {6: "six"}, {7: "seven"}, {8: "eight"}, {9: "nine"}];   

 for(i=0;i<s.length;i++){
        if(!isNaN(parseInt(s[i]))){
            answer+=s[i]
          
        }else{
       var word = s[i];
      // arr의 value값과 같은 것이 있을 때까지 word 채우기
      for (var j = 0; j < arr.length; j++) {
        var valueObj = arr[j];
        for (var key in valueObj) {
          if (valueObj[key] === word) {
            // key값을 answer에 추가
            answer += key;
         word = '';
         break;
          }else{
              word +=s[j+1]
              console.log(word)
              }
          }
        }
      }
    }
    return +answer;
}

처음에 풀려고 했던 방식이다.. key: value를 가진 배열을 만들었고, for문을 돌며 value 값과 같은 값을 가질때까지 

word안에 s[j+1]을 추가한다. 그런데 여기서 또 value의 index를 넣고 하는 방식이 너무 번거로웠고 이게 아닌것 같은 기분이 들었다.

저렇게 순서대로 배치된 배열의 경우 기본적으로 주어지는 index를 잘 활용해야겠다.

 

다른풀이

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);
}

s = 18sevenzerotwo5 라고 가정하고 풀이를 해보자.

반복문이 시작하면, i=0일때 numbers[0], "zero"를 기준으로 문자열을 분할한다.그러면 분할한 문자열은 "18seven"과 "two5로 나누어진다.answer은 arr.join(i)를 통해 "18seven0two5"로 업데이트 된다.

이런식으로 반복을 계속하면 answer은 모두 숫자로 바뀌게 되는 엄청난 코드..!

역시 기본에 충실한게 제일 멋있는듯...