-
[코드 트리] Trail 1 : 프로그래밍 기초 | Ch 8 : 2차원 배열CodeTree 2026. 6. 2. 16:51
8챕터 2차원 배열 공부를 진행했다.
배열 문제를 어려워했던 만큼 2차원 배열도 조금 걱정이 되었지만
막상 모든 문제를 해결하고 이 글을 쓰는 시점에는 2차원 배열은 그렇게 어렵지 않았다는 생각이 든다.
[ 문제 ]


5행 3열로 배치되는 문자들을 모두 대문자로 변경해 출력하는 문제이다.
문제를 풀 때 생각했던 점은 문자를 어떤 방식으로 대문자로 변경할까?라는 부분이었다.
이전 챕터에서 문자들은 모두 아스키코드 값으로 대체될 수 있다고 했다.
그리고 int형으로 형 변환시 모두 아스키코드 값이 출력되는 것도 알았고,
이에 값을 더해주면 다음 문자가 출력됨도 알고 있었다.
아스키코드를 사용하는 것을 생각했다가 이전에 사용해 보았던 char.ToUpper 함수를 사용하기로 생각했다.
값으로 입력되는 문자를 대문자로 변경해주는 함수인데,
해당 함수를 이용해서 간단하게 입력된 위치의 문자를 대문자로 변환시키고
해당 문자를 출력하는 방식으로 5행 3열의 각 문자를 대문자로 변경해 그대로 출력하도록 작성했다.
해설에서는 아스키코드로 해결했다.
해설의 수식은 arr[i,j] + 'A' - 'a'였는데,
대문자의 값이 소문자의 값보다 작기 때문에 'A' - 'a'의 경우 - 32라는 값이 나온다.
이 -32는 결국 소문자 값들이 대문자 값이 되기 위해 빠져야 하는 크기이다.
예시로, 소문자 g의 경우 아스키코드 값이 103이고 대문자 아스키코드 값이 71이므로 32의 값이 빠지면 소문자가 대문자로 변경된다는 사실을 알 수 있다.
이를 이용하면 해설이 작성한 코드처럼 아스키코드를 이용해서 대소문자 변경을 만들어 낼 수 있다.


위 문제는 출력되는 결과가 무엇인지 묻는 선택형 문제였다.
이런 문제가 어려운데, 내가 이 코드를 보고 무엇을 묻는지 이해를 하는 과정이 필요하거나, 혹은 모든 연산을 내가 직접 해보아야 해결할 수 있기 때문이다.
나는 문제를 보고 일일이 해결해서 9라는 답을 얻었고 문제를 해결했다.
끝을 낸 뒤 해설을 보니 정말 신기한 구조였다.
k라는 값을 거쳐갈 수 있는 값인지 확인하고 거쳐갈 수 있다면 1로 변경해 주는? 그런 구조라고 한다.
k가 0일 때, a [1,0] 이 1이고 a [0,2]가 1이라면 1 > 0 > 2라는 경로를 확인한다.
이 경우 a [2,1] 위치에 1을 넣어주면서 해당 위치를 이용해 거쳐갈 수 있음을 표기한다.
이후에도 k가 1일 때 k가 2일 때 각 위치에서 경로를 확인하고 이어진다면 경로 위치에 1을 넣어주면서 모든 공간을 1로 채우는 형태로 마무리된다.
와셜 알고리즘, 이형적 폐쇄를 구하는 공식과 같은 코드라고 하는데,
더 정확히 알아보아야겠지만 정말 신기한 구조라고 생각했다.
처음 그림으로 보았을 때에는 열의 하나의 값을 행의 3개의 값과 함께 대응시키면서 값이 1이라면 교차하는 위치에 1을 집어넣는 형태라고 생각했다.
( 역방향 ㄱ 형태, 십자 형태, 역방향 ㄴ 형태로 열과 행의 값이 1인지 검사하고 있었다. 또 그렇게 각 위치가 1인 경우 각 위치를 이었을 때 만나는 교차점에 1을 넣는다고 생각했다. )
하지만 더 찾아보니 와셜 알고리즘이라는 더 큰 무언가가 있었고 정말 새로운 알고리즘을 알게 되었다.
프로그래밍을 하는 사람이라면 최단 경로 구하는 알고리즘을 공부하면서 해당 알고리즘을 알게 된다고 하는데,
알고리즘 공부를 하게 될 즈음에 나도 이 알고리즘을 다시 한번 정확히 이해하는 시점이 오지 않을까 생각한다.


2차원 배열에도 패턴을 사용하는 문제가 나왔다.
지그제그, 스네이크 방식등의 패턴 문제가 나왔는데,
위 문제는 패턴 문제에서도 보지 못했던 대각선 패턴 문제였다.
대각선을 어떻게 구현해야 하는지 고민을 해보았다.
시작점이 있으면 그다음점은 행과 열이 각각 + 1, - 1이 되는 위치이다.
따라서 나는 첫 번째 행을 쭉 나아가면서 대각선 위치를 찾고 그 위치에 값을 모두 집어넣는 형태로 코드를 작성했다.
나는 열을 사용하지 않고, 첫번째 행과 대각 방향만을 사용했는데,
이 때문에 첫번째 행을 반복하는 횟수가 m + n - 1이라는 형태로 나왔고,
대각 방향은 i + 1만큼 반복하도록 작성했다.
코드를 살펴보면 break와 continue를 사용했다.
이유는 행을 사용하지 않아서 발생하는 없는 위치를 배제하기 위해서이다.
첫 번째 행을 m + n - 1 만큼 반복하는 경우에 위 이미지에서는 6번째 열과 7번째 열이 발생한다.
이는 선언한 arr [n, m]의 바깥 범위(n <= 4, m <= 5)이기 때문에 해당 바깥 범위를 넘어가는 경우,
continue를 사용해서 해당 범위에서는 아무런 동작을 하지 않고 다음 위치를 탐색한다.
다음 위치는 곧 대각 방향이기 때문에, 대각 방향 이동 후 내가 원하는 범위에 들어온다면 그 위치에 값을 저장한다.
이렇게 배열을 대각선으로 쭉 나아가다 보면 j의 범위가 일정 값 이상이 되는 경우가 발생한다.
이는 위의 이미지처럼 행의 길이가 4, 혹은 n이라면 내가 찾을 수 있는 대각 방향의 최대 길이는 n이기 때문에
j가 n 이상인 경우 break를 통해 반복을 종료시킨다.
나는 이렇게 첫 번째 행과 대각으로 진행되는 다중 반복문을 통해 배열에 각 값을 할당하면서 문제를 해결했다.
하지만 해설을 확인하고 되게 어렵게 돌아갔다는 사실을 알았다.
행과 열에 대한 다중 반복문을 사용하고
내부에 while문을 통해 대각 방향 진행을 만들어 주면 된다는 사실을 알게 되었다.



위의 이미지가 해설인데, 해설은 이렇게 말한다.
첫 번째 행을 나아가면서 체크되는 점들의 대각 방향을 모두 찾아 값을 할당한다.
그리고 첫번째 행이 끝나는 지점에서 다음 행을 체크한다.
이렇게 되면 자동적으로 다음 행을 모두 체크하기 때문에 모든 대각 방향에 값을 할당할 수 있다.
해설을 보고 3중 반복문을 사용하려 했던 내 모습이 보이면서도 해설과 같은 답을 내리지 못했다는 것에 조금 아쉬웠다.
결국 나와 해설의 차이는 행을 사용할 것이냐, 말 것이냐 인 것 같다.
해설은 첫 행을 나아가면서 대각 방향에 모든 값을 할당하면, 최종적으로 다음 행들을 사용하기 때문에 행과 열, 대각선 방향을 반복하는 3중 반복문을 사용한 반면,
나는 첫 번째 행을 쭉 나아가면 다음 행에 대한 코드가 필요없을 것이라 생각하여 열과 대각선 방향을 반복하는 2중 반복문을 사용했다. 이 때문에 첫번째 행의 범위를 넘어서는 특정 위치까지 나아가면서 그중 배제되는 부분을 찾아 배제하며 모든 대각 방향에 값을 할당하는 식으로 복잡한 형태로 코드를 작성했다.
약간의 생각차이에서 발생한 코드이지만 사실 내 코드를 읽는 것보다 해설의 코드가 더 읽기가 쉬웠기 때문에 누가 더 대각 패턴이 어떻게 이루어지는지 잘 이해했냐를 물어본다면 해설이 맞지 않을까 생각이 든다.
그래서 3중 반복문을 사용하려 했던 내 모습이 떠오르고 그걸 끝까지 작성하지 않았단 사실에 아쉬운 것 같다.


파스칼의 삼각형 형태로 값을 출력하는 문제이다.
2차원 배열을 사용하며 좋았던 점이 이런 부분인데,
값을 특정 위치에 넣어두기 때문에 그 값을 다른 필요한 곳에 사용하기 좋다는 점이다.
위 문제에서 i , j 위치에 들어가는 값이 i - 1, j - 1 위치 값과 i - 1, j 위치 값을 더한 값이다.
만약 이런 위치 값에 다른 위치 값을 더한 값을 넣는다라고 하면 변수로 따지면 3개의 변수,
그리고 삼각형 형태를 n이라는 크기에 맞추어 쭉 만들어야 하기 때문에 더 많아질 것이다.
하지만 2차원 배열을 통해서 너무 간단하게 그 변수들을 만드는 과정이 사라진다.
위 문제를 풀 때 내가 생각한 점은 첫 번째 열만 1로 초기화하면 되겠다는 생각이었다.
배열 생성 시(new int [n, n]) 초기 값이 모두 0으로 초기화되기 때문에
이후 값은 1,1부터 4,4까지 위치에 맞는 값들을 더해서 할당해 주면 간단히 해결되는 문제라고 생각했다.
이렇게 파스칼의 삼각형 형태로 값을 할당했다면 출력할 때 꼭 패턴대로 출력시켜야 했다.
왜냐하면 나는 n x n 크기의 2차원 배열을 선언하면서 모든 공간을 0으로 초기화했기 때문에,
n x n 크기를 모두 출력하는 경우 파스칼의 삼각형과 함께 나머지 공간은 0으로 출력이 된다.
문제가 원하는 답은 0이 없는 파스칼의 삼각형 부분이기 때문에 패턴에 맞추어(j <= i)
행 크기만큼 열을 출력하도록 작성해 주었다.
2차원 배열을 끝낸 후 생각해 보니, 2차원 배열은 1차원 배열만큼 어렵다고 생각이 들진 않았다.
문제가 쉬웠던 것 같기도 하지만, 패턴을 공부한 후에 문제를 보니까 비슷한 패턴에 대해서는 남아있는 지식으로 잘 해결했던 것 같다.
새로운 알고리즘에 대해서 얕은 공부를 하게 되었고 새로운 패턴인 대각선 방향 패턴을 알게 되었으며,
일반적 입력 이후 패턴 형태의 출력방식으로 꼭 입력일 때 모든 패턴을 사용하는 것은 아니라는 점도 알 수 있었다.
Trail 1이 거의 끝나간다.
하나의 챕터만 남아있는데, 남은 챕터를 끝내고 Trail 2를 향해 나아갈 수 있다면 좋겠다.
'CodeTree' 카테고리의 다른 글
[코드트리] 코드트리 북마크, 복습 루틴 (0) 2026.06.06 [코드트리] 코드트리 학습 루틴 (0) 2026.05.30 [코드 트리] Trail 1 : 프로그래밍 기초 | Ch 6 : 다중 반복문 (0) 2026.05.29 [코드 트리] Trail 1 : 프로그래밍 기초 | Ch 5 : 단순 반복문 (0) 2026.05.26 [코드트리] 1차원 배열 학습 후기 (0) 2026.05.23