문제설명
[[3차]압축](https://school.programmers.co.kr/learn/courses/30/lessons/17684)은은) 문자열을 입력받아 조합할 수 있는 모든 경우의 수를 저장하고 알파벳인 경우 A~Z까지 해당하는 인덱스 번호를, 2개 이상의 단어일 경우 다음 인덱스 번호를 부여하며 사전을 만들어 나가는 문제이다. LZW 압축법을 토대로 문제를 해결하면 된다.
문제해결
우선 키가 되어줄 메서드를 찾아봤다.
알파벳의 인덱스를 구하는 경우도 있었기 때문에 위 메서드를 자주 사용할 거 같았지만 정작 경우의 수를 저장하는 배열, 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;
}
![[Algorithm] [3차] 압축](https://www.notion.so/images/page-cover/gradients_8.png)