[Algorithm] [3차] 압축
공부

[Algorithm] [3차] 압축

작성일: 2023년 10월 26일

문제설명

[[3차]압축](https://school.programmers.co.kr/learn/courses/30/lessons/17684)은은) 문자열을 입력받아 조합할 수 있는 모든 경우의 수를 저장하고 알파벳인 경우 A~Z까지 해당하는 인덱스 번호를, 2개 이상의 단어일 경우 다음 인덱스 번호를 부여하며 사전을 만들어 나가는 문제이다. LZW 압축법을 토대로 문제를 해결하면 된다.

문제해결

우선 키가 되어줄 메서드를 찾아봤다.

  • Str.charCodeAt() => 문자의 아스키코드 반환
  • String.fromCharCode(num) => 역 반환
  • 알파벳의 인덱스를 구하는 경우도 있었기 때문에 위 메서드를 자주 사용할 거 같았지만 정작 경우의 수를 저장하는 배열, dictionary에 알파벳을 반복문으로 편하게 저장하는 것 외에는 외에는 쓸 일이 없었다.

    알파벳 외의 'TO','TB'같은 문자열은 문자열의 첫번째 알파벳 아스키코드가 반환되기 때문에 2글자 이상이고 dictionary에 없는 경우 dictionary의 전체 길이 + 1을 해서 새로운 색인 번호를 부여하는 조건을 줘야했지만 이보다는 더 단순한 방법을 찾고 싶었다.

    두번째는 문자열을 순회할 때 검사한 문자열을 순차적으로 저장하는 방법으로

    KAKAO라면 K,A,K,A,O를 순회하며 K(AKAO) -> (K)A(KAO) -> (KA)KA(O) -> (KAKA)O 가 되어야 하고 이때 왼쪽 괄호의 문자열을 구하면 되는 것이다.

    그렇다면 주어진 문자열을 순회할 때 사전에 새로 등록될 단어 => 현재단어 + 다음단어를 미리 구한 뒤 색인번호는 새로 등록될 단어에서 다음단어를 뺀 단어 => 이미 있는 단어의 색인번호를 구하고 새로 등록될 단어를 사전 배열에 등록하게 되면 사전에는 조회한 모든 단어가 등록되고 색인번호를 저장하는 answer 배열에는 이미 조회한 단어의 색인번호를 등록할 수 있다.

    function solution(msg) {
      // Str.charCodeAt() => 문자의 아스키코드 반환
      // String.fromCharCode(num) => 역 반환
    
      const answer = [];
      const dictionary = [];
      let words = "";
    
      for (let i = 1; i <= 26; i++) {
        const code = String.fromCharCode(i + 64);
        dictionary.push(code);
      }
    
      for (let i = 0; i < msg.length; i++) {
        words += msg[i];
        if (!dictionary.includes(words)) {
          answer.push(dictionary.indexOf(words.slice(0, -1)) + 1);
          dictionary.push(words);
          words = msg[i];
        }
      }
      if (words) answer.push(dictionary.indexOf(words) + 1);
      return answer;
    }