본문 바로가기
코테연습

53. 문자열압축 Javascript

by hxunz 2022. 5. 27.

https://programmers.co.kr/learn/courses/30/lessons/60057

 

코딩테스트 연습 - 문자열 압축

데이터 처리 전문가가 되고 싶은 "어피치"는 문자열을 압축하는 방법에 대해 공부를 하고 있습니다. 최근에 대량의 데이터 처리를 위한 간단한 비손실 압축 방법에 대해 공부를 하고 있는데, 문

programmers.co.kr

 

 

 

 

1. 문제에 대한 이해

  • 우리가 풀어야 할 문제는 무엇인가?
     - 주어진 문자열에서 문자 1개 단위 이상으로 잘라서 압축(중복 개수만큼 자르고 몇번 중복인지 숫자로 나타냄)하고
     - n개 단위의 문자열로 잘라서 압축했을 때 가장 짧게 압축된 문자열의 길이를 구하라
  • 주어진 자료는 무엇인가?
     - 문자열 s
  • 조건은 무엇인가?
     - s는 소문자로 이루어져있다.


2. 계획

  • 이 문제를 푸는데 있어서 유용하게 쓸 수 있는 지식은 무엇인가?
     - 반복문
     - substring으로 문자열 자르기
     - 마지막에 길이 비교할 때 sort() 사용할 수 있을것같다.
  • 만약 문제를 풀 수 없다면 문제를 더 단순하게 하기 위해서 주어진 조건을 버려보아라
     - 예시로 주어진 문자열의 길이를 줄였다. 'aabb'로 줄여보았다.
  • 주어진 자료로부터 유용한 것을 이끌어 낼 수 있는가?
     - 중복 개수만큼 잘라야하니까 반복문을 사용할때 주어진 문자열 s의 길이만큼 반복하지 않고 문자열 s의 길이의 반까지만 반복
     - 예를들어 'aaabb'가 있을때 문자3개 단위로 자른다고 할 경우 'aaa'는 잘라지지만 나머지 'bb'는 문자3개 단위라는 조건에 맞지 않는다.
     - 전체의 길이가 5이기 때문에 3개 단위이상으로 자를 수 없다. 

 

  1. 몇개단위로 문자열을 자를 수 있는지 확인한다.
  2. 이걸 따로 저장해두자 근데 인덱스 0부터니까 몇개단위인지 파악하려면 +1 해줘야된다.

  3. 이 단위를 가지고 for문을 사용해보자
  4. if 현재 자른 문자열이랑 다음에 자른 문자열이랑 같은 경우에 count + 1을 해준다. (단어 앞에 몇번 반복인지 써있어야하니까)

  5. else 안에 또 if문 해서 현재 자른 문자열이랑 다음에 자른 문자열이랑 다른 경우 (동일한 단어의 반복이 끝나는 경우임)
  6. 반복이 한번도 안되면 앞에 1이라는 숫자를 붙이면 안되니까 그냥 현재 자른 문자열만 추가되도록하고
  7. 그렇지않으면 카운트값넣고 문자열 넣어줘야댐 (왜냐 예를들어 aabbaccc이고 단위1일때 a에서 b넘어가는 순간임)

  8. 그리고 count는 초기화 시켜야댐 왜냐 다음 문자열 비교할때 1부터 카운트 해야되니까

  9. 이렇게 한것을 빈배열에 넣어준다음에
  10. sort() 오름차순 정렬해서
  11. 0번째 인덱스 리턴

 

3. 실행

  • 풀이 계획을 실행하고, 각 단계가 올바른지 점검하라.

 

const solution = (s) => {
  let splitArr = [];

  for (i = 0; i < s.length; i++) {
    let unit = i + 1;
    let splitWord = '';
    let count = 1;
    for (j = 0; j < s.length; j = j + unit){
      let currWord = s.substring(j, j + unit);
      let nextWord = s.substring(j + unit, j + unit + unit);
      if (currWord === nextWord) {
        count++;
      } else {
        if (count === 1) {
          splitWord = splitWord + currWord;
        } else {
          splitWord = splitWord + count + currWord;
        }
        count = 1;
      }
    }
    splitArr.push(splitWord);
  }
  const sortSplitArr = splitArr.sort((a, b) => a.length - b.length);

  return sortSplitArr[0].length;
};

test('문자열압축', () => {
  expect(solution("aabb")).toBe(4);
});

 

4. 반성

  • 처음에는 재귀를 사용할 수 있을 것 같다고 생각했었는데 어떻게 재귀로 구현해야할 지 잘 생각이 나지 않았다. for문 대신에 다른 반복문을 사용해볼 수 있을 것 같다. 


 

🫶🏻 Feelings

어제 K번째 수를 풀고 배웠던 정렬 방법을 이 문제에서도 그대로 적용할 수 있어서 뿌듯했다.

 

 

🫶🏻 Findings

계획을 세분화하는 방법을 조금은 알 것 같다. 
계획을 세우는데 한번에 정립이 되지 않아서 

계획을 세우다가 다시 처음으로 돌아가서 조건 추가한다거나,, 계획을 뒤엎고 다시 작성하기도 했다. 

시간이 조금 걸렸지만 정말 계획 대로 실행되도록 코드를 작성하니까 테스트가 통과되더라!

 

변수 이름 정하는것도 중요하다는걸 다시 알게되었다. 

나만 알아볼 수 있으면 되지 하고 대충 result, arr 이런식으로 지었는데 문제가 복잡해지고 코드가 길어지면 

나도 못알아보는 상황이 발생하더라,, 그래서 변수명을 명확하게 할 수 있도록 노력해야겠다!

'코테연습' 카테고리의 다른 글

55. 체육복 Javascript  (0) 2022.05.31
54. 모의고사 Javascript  (0) 2022.05.29
52. K번째수 Javascript  (0) 2022.05.25
51. 위장 Javascript  (0) 2022.05.25
50. 소수 만들기 javascript  (0) 2022.05.24

댓글