🚀 기능 요구 사항

암호문을 좋아하는 괴짜 개발자 브라운이 이번에는 중복 문자를 이용한 새로운 암호를 만들었다. 예를 들어 “browoanoommnaon”이라는 암호문은 다음과 같은 순서로 해독할 수 있다.

  1. “browoanoommnaon”
  2. “browoannaon”
  3. “browoaaon”
  4. “browoon”
  5. “brown”

임의의 문자열 cryptogram이 매개변수로 주어질 때, 연속하는 중복 문자들을 삭제한 결과를 return 하도록 solution 메서드를 완성하라.

제한사항

  • cryptogram은 길이가 1 이상 1000 이하인 문자열이다.
  • cryptogram은 알파벳 소문자로만 이루어져 있다.

실행 결과 예시

코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function problem2(cryptogram) {
if (cryptogram !== cryptogram.toLowerCase()) throw new TypeError('매개변수는 소문자만 입력할 수 있습니다.')
if (!cryptogram.length || cryptogram.length > 1000) throw new RangeError('매개변수는 1자 이상 1000자 이하만 입력할 수 있습니다.')

let strArr = [...cryptogram];
let duplicatedStrPosition = [];
let hasDuplicatedStr = true;

while(hasDuplicatedStr) {
strArr.forEach((_, i, init) => {
if (init[i] === init[i+1]) duplicatedStrPosition = [i, ...duplicatedStrPosition];
})

hasDuplicatedStr = !duplicatedStrPosition.length ? false : true;

duplicatedStrPosition = duplicatedStrPosition.filter(elem => {
strArr = [...strArr.slice(0, elem), ...strArr.slice(elem + 2)];
return false;
})
}

return strArr.join('');
}
  • strArr로 문자열을 배열로 관리
  • strArr 배열이 더 이상 중복이 없을 때 까지 반복해야하고, 문자열의 순회하며 중복을 확인해야 하므로 시간 복잡도 $n^2$
  • Spread문법으로 원본 배열의 변형을 최소화하는 방향으로 배열을 관리
  • for문 대신 배열 메서드 forEach문 사용
  • 원본 배열을 변형시키는 splice 메서드 대신 slice 메서드 사용

🏓 소감

  • 내가 코드를 처음 보는 사람의 입장으로 변수명부터 잘 이해할 수 있는지 고려하여 리팩터링을 하였다.
  • 처음에는 while 조건식을 단순히 true라고 하였는데, 의미를 부여하여 코드의 가독성을 높이기 위해 변수에 할당해주었다.
  • 배열을 다루기 때문에 for문 대신 forEach문을 사용하였다.
  • splice 메서드 같이 원본을 변형시키는 메서드 대신 spread 문법과 slice 메서드를 사용하였다.
  • 리팩터링 전에는 duplicatedStrPosition 배열을 직접 빈 배열로 초기화해주었지만, 리팩터링을 하면서 filter 메서드를 사용하여 좀 더 배열을 다루는 의미를 부여하였다.

하나 걸리는 부분은 제한사항을 에러처리를 해주어야 하나 고민을 하였다. 사용자가 제한사항에 벗어나는 입력을 할 수도 있으므로 이에 대한 에러를 발생시켜주는 것이 사용성에 더 옳다고 생각하여 if 조건문을 통해 에러처리를 해주었습니다.

에러처리에 대해서는 깊게 생각해보지 못했는데, 제한사항에 대해 한번 더 깊이 생각해보면서 에러처리의 필요성을 느낄 수 있었던 문제여서 즐거웠다.

또한 stack 자료구조를 생각하면서 문제를 해석하면 지금의 코드보다 훨씬 더 간결하고 가독성있는 코드를 구현할 수 있다는 것을 오늘 코드리뷰를 통해 깨닫게 되었다. stack으로 구현해보는 것은 다음 시간에 해보도록 하자.