20240131_그림 확대(프로그래머스)

2024. 2. 1. 19:06IT/TIL

오늘의 TIL은 프로그래머스의 그림 확대라는 문제에 대한 내용이다.

 

문제의 링크는 아래와 같다.

 

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

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

문제에 대해 설명하면

 

직사각형 형태의 그림 파일을 나타낸 문자열 배열(string[] picture)과 정수 k가 주어질 때,

 

이 그림 파일을 가로, 세로로 k배 늘린 그림 파일을 나타내도록 문자열 배열을 return 하시오.

 

제한사항

 

1 <= picture의 길이<= 20

1 <= picture의 원소의 길이 <= 20

모든 picture의 원소의 길이는 같다(사각형의 형태를 다 채우는 모습으로 주어짐)

picture의 원소는 '.' 과 'x'로 이루어져 있다.

1 <= k <= 10

 

해결방안

 

간단하게 생각해서 모든 배열의 값들을 k배 해주면 되는데, 이를 어떻게 구현할 것인가가 관건이다.

 

예를 들어서 아래와 같이 조건이 주어지면

string[] picture = { "x.x", 
                     ".x.", 
                     "x.x" };
int k = 3;

 

결과값은 아래와 같다.

string[] answer = { "xxx...xxx", "xxx...xxx", "xxx...xxx", 
                    "...xxx...", "...xxx...", "...xxx...", 
                    "xxx...xxx", "xxx...xxx", "xxx...xxx" };

 

이를 매우 단순하게 생각하면,

 

for 문을 이용해서(혹은 foreach문) 모든 원소에 대해서 k번씩 데이터를 넣어주면되는데,

 

이 아이디어를 사용하여 List를 이용한 코드는 아래와 같다(List를 이용한 이유는 Add 기능을 사용하기 위함).

 

List<string> picList = new List<string>();

foreach (string str in picture)
{
    string picStr = "";
    
    foreach (char c in str)
    {
        for (int i = 0; i < k; i++)
        {
            picStr += c;
        }
    }

    for (int i = 0; i < k; i++)
    {
        picList.Add(picStr);
    }
}

answer = picList.ToArray();

 

우선 List picList를 선언한 후에 foreach 문을 사용한다.

 

우선 string을 담을 picStr을 선언한 후에 picture에 있는 모든 string str을 탐색하면서

 

그 안의 foreach 문을 다시 사용해서 str의 모든 char c에 대해서 k만큼 picStr에 더하여

 

picture의 한 원소(picture[i])를 k배한 값을 만든다.

 

그 후에 이 picStr을 다시 k번씩 picList에 추가하여 k배된 원소를 k번 넣어준다.

 

이 과정을 반복하면 가로로 k배(foreach 문 안의 foreach 문), 세로로 k배(마지막의 for 문)을 할 수 있게 된다.

 

 

 

논리적으로 문제는 없으나 string picStr을 계속 더하는 것은 string의 특성상 매우 좋지 않다.

 

(C#에서 string은 값이 변하는 경우, 이전의 값을 버리고 새로운 값을 만들어 낸다 - 가비지 발생)

 

따라서 이 방법이 아닌 StringBuilder를 사용하는 방법이 보다 효율적이므로 SB를 사용하여 코드를 작성하면 아래와 같다.

 

using System.Text;

List<string> picList = new List<string>();

foreach (string txt in picture)
{
    StringBuilder sb = new StringBuilder();

    foreach (char c in txt)
    {
        sb.Append(new string(c, k));
    }

    string result = sb.ToString();

    for (int i = 0; i < k; i++)
    {
        picList.Add(result);
    }
}

answer = picList.ToArray();

 

우선 StringBuilder를 사용하기 위해서는 using System.Text;로 선언해주고

 

위와 비슷한 방식으로 foreach 문, for 문을 사용하는데,

 

string picStr을 사용하는 대신 StringBuilder를 사용하여 sb.Append(new string(c, k)); 기능을 사용한다.

 

sb.Append(new string(c, k)); 는 sb에 c라는 char를 k번 넣는다는 것이다.

 

이후에 result라는 string을 만들고 sb.ToString();으로 가져온 후 picList에 추가해준다.

 

 

위의 두 코드의 차이점은 StringBuilder를 사용하여 Append하는 부분과

 

string picStr = "";로 선언하고 picStr += c;를 하는 부분인데,

 

이 두 과정에서 StringBuilder를 사용하면 k번 더하지 않고, 한 번에 k개를 추가한 값을 만들지만,

 

picStr += c;를 하면 k번 더하는 과정에서 string이 k개 생기게 된다.

 

이 가비지가 생기는 차이를 최적화 할 수 있는 방법이 StringBuilder라고 할 수 있다.

 

따라서 오늘의 문제를 풀면서 StringBuilder에 대한 기본적인 기능을 공부할 수 있었으며,

 

가비지의 개념과 최적화의 개념을 알 수 있었다. 

 

'IT > TIL' 카테고리의 다른 글

20240202_객체지향의 특징  (0) 2024.02.03
20240201_클래스와 객체  (0) 2024.02.01
20240130_병합 정렬, 힙 정렬  (0) 2024.01.30
20240129_정렬 알고리즘  (0) 2024.01.30
20240126_사원수(쿼터니언)  (1) 2024.01.27