65. [Java] 그림 확대
https://school.programmers.co.kr/learn/courses/30/lessons/181836
- 문자열 배열로 주어진 그림(picture)을 가로, 세로 모두 k배 확대하는 문제이다.
- 즉, 각 문자를 k번 반복해서 가로를 늘리고, 각 줄도 k번 반복해서 세로를 늘리면 된다.
정답코드
import java.util.*;
class Solution {
public String[] solution(String[] picture, int k) {
List<String> list = new ArrayList<>();
for (String row : picture) {
StringBuilder enlargedRow = new StringBuilder();
// 가로 확대
for (char ch : row.toCharArray()) {
for (int i = 0; i < k; i++) {
enlargedRow.append(ch);
}
}
// 세로 확대
for (int i = 0; i < k; i++) {
list.add(enlargedRow.toString());
}
}
return list.toArray(new String[0]);
}
}
- StringBuilder를 써서 각 줄의 문자를 k배로 복제
- 완성된 한 줄을 다시 k번 추가해서 세로도 k배로 복제
- 최종 결과는 List<String>에 담고, 마지막에 배열로 변환해서 리턴
여기서 가로랑 세로의 단위가 다르다는 것이 핵심이다. 가로방향에는 toCharArray()를 쓴다. "문자 하나하나" 단위로 반복하기 때문이다.
반면 세로는 가로 확대가 끝난 후에 만들어진 가로줄 한 줄 전체를 k번 반복하는 로직이므로 굳이 문자 단위 처리를 할 필요 없다. (단순반복문 처리)
나는 String.valueOf().repeat() 메서드를 몰라서 3중 포문으로 작성했는데,
보통 이런 코드는 아래와 같이 2중 for문 + 내부 문자열 반복(String.repeat 또는 StringBuilder) 으로 구현하는 것이 일반적이라고 한다.
import java.util.*;
class Solution {
public String[] solution(String[] picture, int k) {
List<String> result = new ArrayList<>();
for (String row : picture) {
StringBuilder sb = new StringBuilder();
for (char c : row.toCharArray()) {
// 가로 확대
sb.append(String.valueOf(c).repeat(k));
}
// 세로 확대 (k번 같은 줄 추가)
for (int i = 0; i < k; i++) {
result.add(sb.toString());
}
}
return result.toArray(new String[0]);
}
}
여기서 루프 구조를 보면
for (String row : picture)
→ 원본 줄 수만큼 (1중)for (char c : row.toCharArray())
→ 한 줄 문자만큼 (2중)for (int i = 0; i < k; i++)
→ 세로 확대용 반복 (별도 2중)
이전에는 자바에서 문자 하나를 k번 반복한 문자열을 생성하려면 내가 쓴 코드처럼 직접 for
문 돌리거나 StringBuilder
로 만들어야 했는데,
자바 11 이후에는 repeat()
메서드가 생겨서 덕분에 가독성 좋고 코드도 짧아져서 자주 사용된다.
✅ (String.valueOf(c).repeat(count))
String.valueOf(c)
c
는char
타입 (예:'A'
,'1'
등)String.valueOf(c)
는 이char
값을 문자열로 바꿔주는 메서드
repeat(count)
count
는int
타입 (예:1
,2
등)- 문자열을
count
만큼 반복해서 붙인 새 문자열을 반환한다. - 내부적으로는
StringBuilder
를 사용해서 성능도 괜찮다.