Skip to content

Commit 07d55be

Browse files
committed
[level 2] Title: [3차] 압축, Time: 20.05 ms, Memory: 89.4 MB -BaekjoonHub
1 parent 3a72c8a commit 07d55be

2 files changed

Lines changed: 313 additions & 0 deletions

File tree

Lines changed: 247 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,247 @@
1+
# [level 2] [3차] 압축 - 17684
2+
3+
[문제 링크](https://school.programmers.co.kr/learn/courses/30/lessons/17684?language=java)
4+
5+
### 성능 요약
6+
7+
메모리: 89.4 MB, 시간: 20.05 ms
8+
9+
### 구분
10+
11+
코딩테스트 연습 > 2018 KAKAO BLIND RECRUITMENT
12+
13+
### 채점결과
14+
15+
정확성: 100.0<br/>합계: 100.0 / 100.0
16+
17+
### 제출 일자
18+
19+
2026년 01월 04일 20:39:52
20+
21+
### 문제 설명
22+
23+
<h2>압축</h2>
24+
25+
<p>신입사원 어피치는 카카오톡으로 전송되는 메시지를 압축하여 전송 효율을 높이는 업무를 맡게 되었다. 메시지를 압축하더라도 전달되는 정보가 바뀌어서는 안 되므로, 압축 전의 정보를 완벽하게 복원 가능한 무손실 압축 알고리즘을 구현하기로 했다.</p>
26+
27+
<p>어피치는 여러 압축 알고리즘 중에서 성능이 좋고 구현이 간단한 <strong>LZW</strong>(Lempel–Ziv–Welch) 압축을 구현하기로 했다. LZW 압축은 1983년 발표된 알고리즘으로, 이미지 파일 포맷인 GIF 등 다양한 응용에서 사용되었다.</p>
28+
29+
<p>LZW&nbsp;압축은 다음 과정을 거친다.</p>
30+
31+
<ol>
32+
<li>길이가 1인 모든 단어를 포함하도록 사전을 초기화한다.</li>
33+
<li>사전에서 현재 입력과 일치하는 가장 긴 문자열 <code>w</code>를 찾는다.</li>
34+
<li><code>w</code>에 해당하는 사전의 색인 번호를 출력하고, 입력에서 <code>w</code>를 제거한다.</li>
35+
<li>입력에서 처리되지 않은 다음 글자가 남아있다면(<code>c</code>), <code>w+c</code>에 해당하는 단어를 사전에 등록한다.</li>
36+
<li>단계 2로 돌아간다.</li>
37+
</ol>
38+
39+
<p>압축 알고리즘이 영문 대문자만 처리한다고 할 때, 사전은 다음과 같이 초기화된다. 사전의 색인 번호는 정수값으로 주어지며, 1부터 시작한다고 하자.</p>
40+
<table class="table">
41+
<thead><tr>
42+
<th>색인 번호</th>
43+
<th>1</th>
44+
<th>2</th>
45+
<th>3</th>
46+
<th>...</th>
47+
<th>24</th>
48+
<th>25</th>
49+
<th>26</th>
50+
</tr>
51+
</thead>
52+
<tbody><tr>
53+
<td>단어</td>
54+
<td>A</td>
55+
<td>B</td>
56+
<td>C</td>
57+
<td>...</td>
58+
<td>X</td>
59+
<td>Y</td>
60+
<td>Z</td>
61+
</tr>
62+
</tbody>
63+
</table>
64+
<p>예를 들어 입력으로 <code>KAKAO</code>가 들어온다고 하자.</p>
65+
66+
<ol>
67+
<li>현재 사전에는 <code>KAKAO</code>의 첫 글자 <code>K</code>는 등록되어 있으나, 두 번째 글자까지인 <code>KA</code>는 없으므로, 첫 글자 <code>K</code>에 해당하는 색인 번호 11을 출력하고, 다음 글자인 <code>A</code>를 포함한 <code>KA</code>를 사전에 27 번째로 등록한다.</li>
68+
<li>두 번째 글자 <code>A</code>는 사전에 있으나, 세 번째 글자까지인 <code>AK</code>는 사전에 없으므로, <code>A</code>의 색인 번호 1을 출력하고, <code>AK</code>를 사전에 28 번째로 등록한다.</li>
69+
<li>세 번째 글자에서 시작하는 <code>KA</code>가 사전에 있으므로, <code>KA</code>에 해당하는 색인 번호 27을 출력하고, 다음 글자 <code>O</code>를 포함한 <code>KAO</code>를 29 번째로 등록한다.</li>
70+
<li>마지막으로 처리되지 않은 글자 <code>O</code>에 해당하는 색인 번호 15를 출력한다.</li>
71+
</ol>
72+
<table class="table">
73+
<thead><tr>
74+
<th>현재 입력(w)</th>
75+
<th>다음 글자(c)</th>
76+
<th>출력</th>
77+
<th>사전 추가(w+c)</th>
78+
</tr>
79+
</thead>
80+
<tbody><tr>
81+
<td>K</td>
82+
<td>A</td>
83+
<td>11</td>
84+
<td>27: KA</td>
85+
</tr>
86+
<tr>
87+
<td>A</td>
88+
<td>K</td>
89+
<td>1</td>
90+
<td>28: AK</td>
91+
</tr>
92+
<tr>
93+
<td>KA</td>
94+
<td>O</td>
95+
<td>27</td>
96+
<td>29: KAO</td>
97+
</tr>
98+
<tr>
99+
<td>O</td>
100+
<td></td>
101+
<td>15</td>
102+
<td></td>
103+
</tr>
104+
</tbody>
105+
</table>
106+
<p>이 과정을 거쳐 다섯 글자의 문장 <code>KAKAO</code>가 4개의 색인 번호 [11, 1, 27, 15]로 압축된다.</p>
107+
108+
<p>입력으로 <code>TOBEORNOTTOBEORTOBEORNOT</code>가 들어오면 다음과 같이 압축이 진행된다.</p>
109+
<table class="table">
110+
<thead><tr>
111+
<th>현재 입력(w)</th>
112+
<th>다음 글자(c)</th>
113+
<th>출력</th>
114+
<th>사전 추가(w+c)</th>
115+
</tr>
116+
</thead>
117+
<tbody><tr>
118+
<td>T</td>
119+
<td>O</td>
120+
<td>20</td>
121+
<td>27: TO</td>
122+
</tr>
123+
<tr>
124+
<td>O</td>
125+
<td>B</td>
126+
<td>15</td>
127+
<td>28: OB</td>
128+
</tr>
129+
<tr>
130+
<td>B</td>
131+
<td>E</td>
132+
<td>2</td>
133+
<td>29: BE</td>
134+
</tr>
135+
<tr>
136+
<td>E</td>
137+
<td>O</td>
138+
<td>5</td>
139+
<td>30: EO</td>
140+
</tr>
141+
<tr>
142+
<td>O</td>
143+
<td>R</td>
144+
<td>15</td>
145+
<td>31: OR</td>
146+
</tr>
147+
<tr>
148+
<td>R</td>
149+
<td>N</td>
150+
<td>18</td>
151+
<td>32: RN</td>
152+
</tr>
153+
<tr>
154+
<td>N</td>
155+
<td>O</td>
156+
<td>14</td>
157+
<td>33: NO</td>
158+
</tr>
159+
<tr>
160+
<td>O</td>
161+
<td>T</td>
162+
<td>15</td>
163+
<td>34: OT</td>
164+
</tr>
165+
<tr>
166+
<td>T</td>
167+
<td>T</td>
168+
<td>20</td>
169+
<td>35: TT</td>
170+
</tr>
171+
<tr>
172+
<td>TO</td>
173+
<td>B</td>
174+
<td>27</td>
175+
<td>36: TOB</td>
176+
</tr>
177+
<tr>
178+
<td>BE</td>
179+
<td>O</td>
180+
<td>29</td>
181+
<td>37: BEO</td>
182+
</tr>
183+
<tr>
184+
<td>OR</td>
185+
<td>T</td>
186+
<td>31</td>
187+
<td>38: ORT</td>
188+
</tr>
189+
<tr>
190+
<td>TOB</td>
191+
<td>E</td>
192+
<td>36</td>
193+
<td>39: TOBE</td>
194+
</tr>
195+
<tr>
196+
<td>EO</td>
197+
<td>R</td>
198+
<td>30</td>
199+
<td>40: EOR</td>
200+
</tr>
201+
<tr>
202+
<td>RN</td>
203+
<td>O</td>
204+
<td>32</td>
205+
<td>41: RNO</td>
206+
</tr>
207+
<tr>
208+
<td>OT</td>
209+
<td></td>
210+
<td>34</td>
211+
<td></td>
212+
</tr>
213+
</tbody>
214+
</table>
215+
<h3>입력 형식</h3>
216+
217+
<p>입력으로 영문 대문자로만 이뤄진 문자열 <code>msg</code>가 주어진다. <code>msg</code>의 길이는 1 글자 이상, 1000 글자 이하이다.</p>
218+
219+
<h3>출력 형식</h3>
220+
221+
<p>주어진 문자열을 압축한 후의 사전 색인 번호를 배열로 출력하라.</p>
222+
223+
<h3>입출력 예제</h3>
224+
<table class="table">
225+
<thead><tr>
226+
<th>msg</th>
227+
<th>answer</th>
228+
</tr>
229+
</thead>
230+
<tbody><tr>
231+
<td><code>KAKAO</code></td>
232+
<td>[11, 1, 27, 15]</td>
233+
</tr>
234+
<tr>
235+
<td><code>TOBEORNOTTOBEORTOBEORNOT</code></td>
236+
<td>[20, 15, 2, 5, 15, 18, 14, 15, 20, 27, 29, 31, 36, 30, 32, 34]</td>
237+
</tr>
238+
<tr>
239+
<td><code>ABABABABABABABAB</code></td>
240+
<td>[1, 2, 27, 29, 28, 31, 30]</td>
241+
</tr>
242+
</tbody>
243+
</table>
244+
<p><a href="http://tech.kakao.com/2017/11/14/kakao-blind-recruitment-round-3/" target="_blank" rel="noopener">해설 보러가기</a></p>
245+
246+
247+
> 출처: 프로그래머스 코딩 테스트 연습, https://school.programmers.co.kr/learn/challenges
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import java.util.*;
2+
/*
3+
글자가 있어
4+
1. 현 글자와 다음 글자를 합쳐
5+
2. 합친 글자가 없어.
6+
3. 현 글자 색인 출력
7+
4. '현 글자 + 다음 글자'사전 추가
8+
글자가 없어.
9+
10+
11+
*/
12+
13+
class Solution {
14+
15+
char[] strs;
16+
HashMap<String, Integer> map = new HashMap<String, Integer>();
17+
List<Integer> answer = new ArrayList<>();
18+
public int[] solution(String msg) {
19+
preSetting();
20+
strs = msg.toCharArray();
21+
22+
for(int i = 0; i < strs.length; i++){
23+
i = find(i);
24+
}
25+
26+
return answer.stream().mapToInt(i -> i).toArray();
27+
}
28+
29+
int find(int idx){
30+
int ans = 0;
31+
String now = "";
32+
33+
for(; idx < strs.length; idx++){
34+
now += strs[idx];
35+
36+
if(map.containsKey(now)){
37+
ans = map.get(now);
38+
}else{
39+
map.put(now, map.size() + 1);
40+
break;
41+
}
42+
}
43+
// System.out.println(now + " " + ans + " : " + idx);
44+
answer.add(ans);
45+
return idx - 1;
46+
}
47+
48+
49+
50+
void preSetting(){
51+
String[] w = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".split("");
52+
for(int i = 1; i < 27; i++){
53+
map.put(w[i - 1], i);
54+
}
55+
}
56+
}
57+
58+
59+
60+
/*
61+
for(Map.Entry<String, Integer> test: map.entrySet()){
62+
System.out.println(test.getValue() + " " + test.getKey());
63+
}
64+
65+
66+
*/

0 commit comments

Comments
 (0)