프로그래머스, 숫자 문자열과 영단어(level 1)

껌뻑이·2021년 8월 24일
0

Programmers

목록 보기
1/6
post-thumbnail

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

문제

문제를 이해하는 것에는 어렵지 않았다.
s라는 문자열에 일부 숫자가 영단어로 바꿔어졌거나, 바뀌지 않고 그대로 숫자가 들어있다.
ex) const s = "one4seveneight"

이러한 s안의 문자열로나타낸 숫자를 진짜 숫자로 바꾸어서 숫자로 리턴하면 되는 문제이다.

다음 표는 숫자에 대응되는 영단어이다.

숫자영단어
0zero
1one
2two
3three
4four
5five
6six
7seven
8eight
9nine

나의 풀이

영단어에 맞게 숫자가 주어졌다. 나는 이것을 배열로 생각했다.

const words = [
  "zero",
  "one",
  "two",
  "three",
  "four",
  "five",
  "six",
  "seven",
  "eight",
  "nine",
];

이렇게 하면 index번호와 배열의 값이 맞게 된다.

그리고 forEach와 includes, replace를 통해 하나씩 체크하고 발견되면 바꿔주는 것으로 생각했다.

그 후 s를 Number()로 숫자로 형변환을 해주어 return을 하면 될 것이라고 생각했다.

words.forEach((word, i) => {
  if (s.includes(word)) {
    s = s.replace(word, i);
  }
});

return Number(s)

테스트 결과는 모두 통과했다.

그리고 아무 걱정없이 채점을 했는데 70점을 맞았다...

나는 뭐가 잘못되었는지 모르고 있었다.

내가 놓친 부분

내가 replace의 동작 원리를 놓치고 있었다.

replace는 발견된 첫번째 문자열만 치환해준다는 것이다.

s를 'oneoneone'이라고 가정하고 코드를 돌려보자.

const s = 'oneoneone';

const words = [
  "zero",
  "one",
  "two",
  "three",
  "four",
  "five",
  "six",
  "seven",
  "eight",
  "nine",
];

words.forEach((word, i) => {
  if (s.includes(word)) {
    s = s.replace(word, i);
  }
});

return Number(s)

결과는 NaN이 나온다. number가 아니라는 것이다.
그러면 s를 Number()하기 전을 확인해보면 s는 '1oneone'이 된다.

즉, 첫번째 one만 1로 바꿔주고 나먼지 oneone은 지나가는 것이다.

해결 방법

내가 생각나는 해결방법은 2가지였다.
replaceAll은 프로그래머스에서 사용이 안된다.

1. replaceAll의 동작원리로 구현하기

function replaceAll(searchValue, replaceValue){
  searchValue.split(searchValue).join(replaceValue)
}

기존 문자열을 찾는 값으로 구분하여 나눠주고 배열을 만든다.
ex) 1one1 => ['1', '1']

그리고 다시 합칠때는 구분자로 바꾸려는 값을 넣어서 합쳐준다.
ex) ['1', '1'] => 111

이러한 원리를 이용하여 다시 풀이를 해보았다.

const words = [
  "zero",
  "one",
  "two",
  "three",
  "four",
  "five",
  "six",
  "seven",
  "eight",
  "nine",
];

words.forEach((word, i) => {
  if (s.includes(word)) {
    s= s.split(word).join(i);
  }
});

return Number(s)

2. 정규표현식을 활용

정규 표현식을 쓰면 코드가 좀 지저분해 보일 수 있지만 알맞은 풀이를 할 수 있다.

s = s.replace(/zero/g, 0)
    .replace(/one/g, 1)
    .replace(/two/g, 2)
    .replace(/three/g, 3)
    .replace(/four/g, 4)
    .replace(/five/g, 5)
    .replace(/six/g, 6)
    .replace(/seven/g, 7)
    .replace(/eight/g, 8)
    .replace(/nine/g, 9)
    return Number(s);

정규표현식의 플래그에 g를 넣어주어 모든 문자를 검색하여 replaceAll과 같은 효과를 주었다.

결론

간단한 문제였지만 내가 예외적인 테스트케이스를 생각하지 못해서 시간을 뺏겼다. 그리고 replace의 동작 원리를 제대로 파악하지 못했다. 이런 문제를 또 풀게되면 금방 맞출 수 있을 것 같다!!

0개의 댓글