🚀 기능 요구 사항 암호문을 좋아하는 괴짜 개발자 브라운이 이번에는 중복 문자를 이용한 새로운 암호를 만들었다. 예를 들어 “browoanoommnaon”이라는 암호문은 다음과 같은 순서로 해독할 수 있다.
“browoanoommnaon”
“browoannaon”
“browoaaon”
“browoon”
“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으로 구현해보는 것은 다음 시간에 해보도록 하자.
댓글 공유