Skip to main content

65. [Java] 그림 확대

https://school.programmers.co.kr/learn/courses/30/lessons/181836

image.png

image.png

image.png

image.png

image.png

  • 문자열 배열로 주어진 그림(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]);
    }
}
  1. StringBuilder를 써서 각 줄의 문자를 k배로 복제
  2. 완성된 한 줄을 다시 k번 추가해서 세로도 k배로 복제
  3. 최종 결과는 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)
    • cchar 타입 (예: 'A', '1' 등)
    • String.valueOf(c)는 이 char 값을 문자열로 바꿔주는 메서드

  • repeat(count)
    • countint 타입 (예: 1, 2 등)
    • 문자열을 count만큼 반복해서 붙인 새 문자열을 반환한다.
    • 내부적으로는 StringBuilder를 사용해서 성능도 괜찮다.