D.evelop [CS]/Algorithm

[Algorithm 017] JS - 숫자 문자열과 영단어 (2021 카카오 채용연계형 인턴십)

Danne 2021. 11. 3. 20:01

문제 출처 : 프로그래머스 prorammers  - 2021 카카오 채용연계형 인턴십 문제 (링크)

 

 

숫자 문자열과 영단어 

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

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

  • 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로 주어집니다.

 


 

 

솔직히 그냥 문제만 보고는 풀지 못했다.

다른 사람의 풀이를 참고해 다시 작성했고, 내가 이해하고 푼건지 자동적으로 외워진건지 모르겠다.

 

처음 접근 법

function solution(s) {
  var answer = 0;
  let objNums = {
      "zero" : 0,
      "one" : 1,
      "two" : 2,
      "three" : 3,
      "four" : 4,
      "five" : 5,
      "six" : 6,
      "seven" : 7,
      "eight" : 8,
      "nine" : 9,
  }
  const keys = Object.keys(objNums)
  parseInt(answer)
  return answer;
}

 

 

1. 서로 대응하는 문자열과 숫자를 key와 value값을 으로 짝을지어 객체로 선언
2. 해당 key값에 해당하는 값으로 문자열을 숫자로 교체

 

여기서 2번에서 막혔다.

문자열은 배열로 들어오는게 아니다. ["one", 4, "seven", "eight"]이런 식이 아닌 "one4seveneight"이렇게 들어온다.

이 문자열을 어느 기준으로 잘라야 할지에 대해 막혔다.

 

몰라도 일단 정수로 출력하려고 parseInt()는 써둠

 

 

다른 사람의 풀이를 참고해 수정해 적용

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

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

가장 많은 사람들의 좋아요를 받았던, 배열과 split, join메서드를 이용한 풀이 

split (MDN 명세)
join (MDN 명세)

풀이를 보고나니 '배열의 index가 0 ,1, 2, 3...이렇게 시작되는데, 그걸 이용하면 "zero는 0이다"이런 식으로 안풀어도 됐잖아?'하는 깨달음.

 

1. numbers 배열을 돌 for문 선언.

2. s값을 split를 이용해 numbers[i] 값에 해당하는 문자를 잘라낸다. 그 값을 arr 라는 배열에 담는다.

[ '', '4seveneight' ]

 

2. 그 arr배열에 join 함수를 이용해 해당 인덱스 ( i ) 이용해 연결한다.

[ '14seveneight' ]
// 여기서 맨 앞의 1은 one이 교체됐다기보다
// numbers[0]의 값''과 numbers[1]의 값'4seveneight'을 
// 현재 i값인 1이 연결해준다고 보면된다.

 

// 다음과 같은 argument로 호출 시, for문을 통한 arr값 변화
solution("one4seveneight") 

'arr' [ 'one4seveneight' ]
'arr' [ '', '4seveneight' ]
'arr' [ '14seveneight' ]
'arr' [ '14seveneight' ]
'arr' [ '14seveneight' ]
'arr' [ '14seveneight' ]
'arr' [ '14seveneight' ]
'arr' [ '14', 'eight' ]
'arr' [ '147', '' ]
'arr' [ '1478' ]

 

그리고 의문?🤔

이 결과를 내기 위해서 zero에서 nine 까지 총 10번의 루프를 무조건 실행하게 된다.

위의 과정에서 3, 4, 5, 6, 7의 케이스는 조금 아까운 작업 같다는 생각.🧐

만약 숫자로만 이루어진 값인 solution("123")을 호출해도, 이 3개의 문자를 체킹하기 위해 9번의 for문을 돌아야한다.

solution("123")
'arr' [ '123' ]
'arr' [ '123' ]
'arr' [ '123' ]
'arr' [ '123' ]
'arr' [ '123' ]
'arr' [ '123' ]
'arr' [ '123' ]
'arr' [ '123' ]
'arr' [ '123' ]
'arr' [ '123' ]

 

그리고 제한 사항의 조건을 좀 더 추가하면 데이터 양이 많아 졌을 때, 예외 사항에 대한 계산에 낭비될 과정을 줄일 수 있지 않을까?

 

방법을 좀 더 생각해보자.

 

 

 

반응형