1. 지그재그 배열과 2차원 배열의 차이점
드디어 "배열의 배열" 또는 "지그재그 배열" (영어로는 jagged arrays) 주제까지 왔네! 2차원 배열이랑 다르게, 지그재그 배열은 각 열의 길이가 다를 수 있어. 예를 들어, 여러 건물이 있는데 각 건물마다 아파트 수가 다 다른 거지 — 어떤 건물은 5개, 어떤 건물은 20개, 또 어떤 건물은 1개만 있는 것처럼.
지그재그 배열은 각 요소가 또 다른 배열인 배열이야. 그리고 내부 배열(이걸 "서브배열"이라고도 해)은 길이가 다를 수 있어.
주요 차이점:
- 2차원 배열에서는 각 "행"(그리고 "열")마다 요소 개수가 똑같아. 예시: int[,] grid = new int[3, 5]; — 항상 3행 5열이야.
- 지그재그 배열에서는 각 행의 길이가 다를 수 있어! 예시: int[][] jagged = new int[3][]; — 그리고 각 행(서브배열)을 따로 초기화해야 해.
비주얼로 보면 이래:
| 2차원 배열 | 지그재그 배열 | |
|---|---|---|
| 요소 개수 | 고정됨 (예: 3x5) | 행마다 다를 수 있음 |
| 인덱싱 | |
|
| 유연성 | 낮음 | 높음 |
| 사용 예시 | 테이블, 수학 | 불규칙 데이터: 학생별로 다른 개수의 점수, 삼각형 등 |
비주얼: 2차원 배열 vs 지그재그 배열
2차원 배열 (3x3):
┌───┬───┬───┐
│ 1 │ 2 │ 3 │
├───┼───┼───┤
│ 4 │ 5 │ 6 │
├───┼───┼───┤
│ 7 │ 8 │ 9 │
└───┴───┴───┘
지그재그 배열 (길이 다름):
┌───┬───┐
│ 1 │ 2 │
├───┼───┼───┬───┐
│ 3 │ 4 │ 5 │ 6 │
├───┼───┴───┴───┘
│ 7 │
└───┘
2. 지그재그 배열 선언과 초기화 문법
지그재그 배열 선언, 생각보다 별거 없어! 대괄호 두 개 있다고 겁먹지 마:
int[][] jaggedArray = new int[3][];
이건 3개의 요소를 가진 배열이고, 각 요소도 int 배열이야. 근데 아직 내부 배열들은 안 만들어졌어! 좀 더 자세히 볼게.
지그재그 배열 단계별 초기화
1단계 — 외부(메인) 배열 만들기:
int[][] jaggedArray = new int[3][];
이제 3개의 "행"이 생겼지만, 전부 null이야.
2단계 — 내부 배열(서브배열) 만들고 채우기:
예를 들어, 첫 번째 행은 길이 2, 두 번째는 4, 세 번째는 3으로 해보자:
jaggedArray[0] = new int[2]; // 첫 번째 행에 2개
jaggedArray[1] = new int[4]; // 두 번째 행에 4개
jaggedArray[2] = new int[3]; // 세 번째 행에 3개
3단계 — 값 채우기:
내부 배열은 그냥 일반 배열이야! 예시:
jaggedArray[0][0] = 1;
jaggedArray[0][1] = 2;
jaggedArray[1][0] = 3;
jaggedArray[1][1] = 4;
jaggedArray[1][2] = 5;
jaggedArray[1][3] = 6;
jaggedArray[2][0] = 7;
jaggedArray[2][1] = 8;
jaggedArray[2][2] = 9;
지그재그 배열 간단 초기화
값을 미리 알고 있다면 한 번에 만들고 채울 수도 있어:
int[][] jaggedArray = new int[][]
{
new int[] { 1, 2 },
new int[] { 3, 4, 5, 6 },
new int[] { 7, 8, 9 }
};
혹은 내부 배열 타입 생략해서 더 짧게:
int[][] jaggedArray = {
new[] { 1, 2 },
new[] { 3, 4, 5, 6 },
new[] { 7, 8, 9 }
};
3. 지그재그 배열 반복문과 사용법
지그재그 배열 반복문도 2차원 배열이랑 비슷해. 바깥쪽 for는 행, 안쪽 for는 각 행의 요소(길이 다를 수 있음) 도는 거야:
for (int i = 0; i < jaggedArray.Length; i++)
{
Console.WriteLine($"행 {i}:");
for (int j = 0; j < jaggedArray[i].Length; j++)
{
Console.Write($"{jaggedArray[i][j]} ");
}
Console.WriteLine();
}
결과 화면:
행 0:
1 2
행 1:
3 4 5 6
행 2:
7 8 9
foreach로 인덱스 신경 안 쓰고도 가능해:
foreach (int[] row in jaggedArray)
{
foreach (int value in row)
{
Console.Write($"{value} ");
}
Console.WriteLine();
}
4. 배열의 배열 구조
이제 배열의 배열이 실제로 어떻게 생겼는지 알려줄게. 준비됐지?
일반 배열은 "배열 변수는 배열 요소를 담는 컨테이너의 참조를 저장"해. 근데 지그재그 배열은 좀 더 복잡해: 배열의 배열 변수는 "1차원 배열들의 참조를 담는 컨테이너"의 참조를 저장해. 백 번 설명하는 것보다 한 번 보는 게 나으니까:
왼쪽은 "배열의 배열 변수"가 "배열 컨테이너 객체"의 참조를 저장하는 거고, 가운데는 "배열 컨테이너 객체"의 각 칸에 1차원 배열(지그재그 배열의 행) 참조가 들어있어. 그리고 오른쪽엔 4개의 1차원 배열(우리 지그재그 배열의 행)이 보여.
이게 지그재그 배열의 실제 구조야. 이런 구조 덕분에 C# 프로그래머는 몇 가지 장점이 있어:
첫째, "컨테이너의 컨테이너"가 "행 배열"의 참조를 저장하니까, 행을 쉽게 바꿀 수 있어. "컨테이너의 컨테이너"에 접근하려면 인덱스 하나만 쓰면 돼. 예시:int[][] data = new int[2][];
data[0] = new int[5]; // 첫 번째 행 — 5개짜리 배열
data[1] = new int[5]; // 두 번째 행 — 5개짜리 배열
int[] row1 = data[0];
int[] row2 = data[1];
이런 식으로 행을 바꿀 수도 있어:
// 중요한 데이터 매트릭스
int[][] matrix = {
new int[] {1, 2, 3, 4, 5},
new int[] {5, 4, 3, 2, 1}
};
int[] tmp = matrix[0];
matrix[0] = matrix[1];
matrix[1] = tmp;
2차원 배열에서 배열 이름 뒤에 인덱스 하나만 쓰면, "컨테이너의 컨테이너"에 접근하는 거야. 그 칸에는 1차원 배열 참조가 들어있지.
5. 지그재그 배열이 더 좋은 상황
언제 지그재그 배열이 2차원 배열보다 유리할까?
- 각 사용자마다 다른 개수의 데이터를 저장할 때: 과목별 점수, 구매 내역, 댓글 등.
- 데이터가 삼각형이나 계단형 구조일 때(예: 피라미드, 파스칼 삼각형 등).
- 메모리 아끼고 싶을 때: 2차원 배열은 행이 고정, 지그재그 배열은 필요한 만큼만.
실생활 예시: 학생 점수 매니저
우리 프로젝트를 확장해보자! 학생마다 과목별로 점수 개수가 다를 수 있어. 어떤 학생은 과제 많이 내고, 어떤 학생은 적게 내고. 이럴 때 지그재그 배열이 딱이야.
예를 들어, 수학 과제 점수:
| 학생 | 점수 |
|---|---|
| 0 | 5, 4 |
| 1 | 3, 4, 4 |
| 2 | 5 |
이렇게 배열 선언:
int[][] studentMarks = new int[3][];
studentMarks[0] = new int[] { 5, 4 }; // 첫 번째 학생 - 2개 점수
studentMarks[1] = new int[] { 3, 4, 4 }; // 두 번째 학생 - 3개 점수
studentMarks[2] = new int[] { 5 }; // 세 번째 학생 - 1개 점수
각 학생 점수 출력:
for (int i = 0; i < studentMarks.Length; i++)
{
Console.Write($"학생 {i}: ");
for (int j = 0; j < studentMarks[i].Length; j++)
{
Console.Write(studentMarks[i][j] + " ");
}
Console.WriteLine();
}
다른 타입과 지그재그 배열
지그재그 배열은 뭐든 담을 수 있어: string, 배열의 배열(더 깊게!), 네가 만든 객체도 가능.
예시: string 배열
string[][] groups = new string[][]
{
new string[] { "이반", "표트르" },
new string[] { "마리야", "알렉세이", "세르게이" },
new string[] { "바실리사" }
};
6. 특징과 흔한 실수
지그재그 배열은 유연하지만, 함정도 많아.
- 내부 배열을 초기화 안 하면(jaggedArray[1] = ...), 접근 시 NullReferenceException 나와. 꼭 내부 배열 하나씩 초기화해!
- 모든 행(서브배열)이 같은 길이가 아냐. 두 번째 인덱스 고정해서 쓰면 범위 벗어날 수 있어.
- 2차원 배열이랑 헷갈리지 마! 인덱싱은 array[i][j]이고, array[i, j] 아냐.
GO TO FULL VERSION