10.6 다차원 배열
배열이 중요하긴한가봅니다. 3개를 했는데도 10.6이네요. 3에서도 안끝날것같은데? 뭐, 시작합시다.
다차원 배열이란 차원이 둘 이상인 배열을 말합니다. 전 시간에 배운 2차원 배열도 다차원 배열에 해당하고, 다차원 배열을 선언하는 문법은 2차원 배열의 문법과 같습니다. 다만 차원이 늘어날수록 요소에 접근할 때 사용하는 인덱스의 수가 한 개씩 늘어날 뿐입니다. C#이다의 저자는 3차원 이상의 배열을 사용하지 말라고 권하고 있습니다. 이유는 3차원 배열은 그림으로 옮기기 쉽지않다고 하네요. 그림으로 그리기 쉽지 않다는 것은 머릿속에 배열의 내용을 유지하기 어렵다는 이야기입니다. 자신도 이해하지 못하는 코드가(...) 제대로 동작하기를 '바라며' 작성하게 됩니다. 디버깅은 프로그래밍 작성보다 10배 어렵다고 하는데, 이 말을 근거하면 작성할 때 조차 완벽하게 이해하지 못하는 코드를 디버깅한다는 것은 불가능이라 봐야합니다. 유지보수가 안된다는 것입니다. (Chat GPT와 구글링 복사를 하는 작성자는 이 글을 읽고 쓰며 반성하고있습니다.) 아무튼, 다차원 배열을 마구 사용한다면 도망치라는 저자의 말을 마지막으로 하고... 예제로 다차원 배열을 보시죠!
namespace _3DArray
{
class Program
{
static void Main(string[] args)
{
int[,,] array = new int[4, 3, 2]
{
{ {1, 2}, {3, 4}, {5, 6} },
{ {1, 2}, {3, 4}, {5, 6} },
{ {1, 2}, {3, 4}, {5, 6} },
{ {1, 2}, {3, 4}, {5, 6} },
};
for (int i = 0; i <array.GetLength(0); i++)
{
for (int j = 0; j < array.GetLength(1); j++)
{
Console.Write("{ ");
for (int k = 0; k < array.GetLength(2); k++)
{
Console.Write($"{array[i,j,k]} ");
}
Console.Write("} ");
}
Console.WriteLine();
}
}
}
}[실행 결과]
{ 1 2 } { 3 4 } { 5 6 }
{ 1 2 } { 3 4 } { 5 6 }
{ 1 2 } { 3 4 } { 5 6 }
{ 1 2 } { 3 4 } { 5 6 }10.7 가변 배열
2차원 배열과 3차원 배열 같은 다차원 배열을 '배열의 요소로 갖는 배열' 이라고 설명했는데, 사실 진정한 의미에서 배열을 요소로 갖는 배열은 가변 배열(Jagged Array)입니다. 가변 배열은 다양한 길이의 배열을 요소로 갖는 다차원 배열로 이용됩니다.가변 배열은 다차원 배열과 달리 배열의 요소로 사용해 접근할 수 있는 겁니다. 예를들어 첨자를 2차원 배열이라 두개를 꼭 사용해야만 했었는데 그럴 필요가 없는것이죠. 참고로 Jagged란 '들쭉날쭉'이라는 뜻입니다. 예제를 함께 보시죠.
[가별 배열 형식]
데이터_형식[][] 배열_이름 = new 데이터_형식[가변_배열의_용량][];
[선언 예시 : 용량이 3개인 배열 jagged 선언]
int[][] jagged = new int[3][];
jagged[0] = new int[5] { 1, 2, 3, 4, 5 };
jagged[1] = new int[] {10, 20, 30};
jagged[2] = new int[] { 100, 200 };
[선언과 동시에 초기화 : 가변 배열의 요소는 '배열'이다.]
int[][] jagged2 = new int[2][]
{
new int[] { 300, 400},
new int[4] { 6, 7, 8, 9 }
};namespace JaggedArray
{
class Program
{
static void Main(string[] args)
{
int[][] jagged = new int[3][];
jagged[0] = new int[5] { 1, 2, 3, 4, 5 };
jagged[1] = new int[] { 10, 20, 30 };
jagged[2] = new int[] { 100, 200 };
foreach (int[] arr in jagged)
{
Console.Write($"Length : {arr.Length}, ");
foreach (int e in arr)
{
Console.Write($"{e} ");
}
Console.WriteLine("");
}
Console.WriteLine("");
int[][] jagged2 = new int[2][]
{
new int[] { 300, 400},
new int[4] { 6, 7, 8, 9 }
};
foreach (int[] arr in jagged2)
{
Console.Write($"Length : {arr.Length}, ");
foreach(int e in arr)
{
Console.Write($"{e} ");
}
Console.WriteLine("");
}
}
}
}[실행 결과]
Length : 5, 1 2 3 4 5
Length : 3, 10 20 30
Length : 2, 100 200
Length : 2, 300 400
Length : 4, 6 7 8 910.8 컬렉션 맛보기
컬렉션(Collection)이란 같은 성격을 띤 데이터의 모음을 담는 자료 구조(Data Structure)를 말합니다. 지금 배우고있는 배열도 .NET이 제공하는 다양한 컬렉션 자료구조중 하나입니다.
public abstract class Array : ICloneable, IList, ICollection, IEnumerable.NET의 컬렉션들이 필수적으로 상속해야하는 ICollection 인터페이스를 상속함으로써 System.Array는 컬렉션 자료구조임을 알수 있습니다. .NET은 배열 말고도 [ ArrayList, Queue, Stack, Hashtable ]이라는 자료구조 특징의 컬렉션을 소유하고있습니다. 먼저 ArrayList 입니다!
10.8.1 ArrayList
ArrayList는 배열과 가장 닮은 컬렉션입니다. 컬렉션 요소에 접근할 때는 [ ] 연산자를 이용하고, 특정 위치에 있는 요소에 데이터를 임의로 할당도 합니다. 물론 배열과 달리 컬렉션을 생성할 때 용량을 미리 지정할 필요 없이 자동으로 용량이 늘거나 줄어드는게 ArrayList의 큰 장점입니다. ArrayList가 사용하는 메소드로는 Add(), RemoveAt(), Insert() 이며, 이중 Add()와 Insert()는 다양한 형식의 객체를 담을 수 있습니다.
object의 형식의 매개변수를 받고있기 때문입니다.그래서 Add에는 int 형식으로 정수 형식으로 입력되지않고 object 형식으로 박싱(Boxing)되어 입력이 되어버리고, ArrayList의 요소에 접근해서 사용할땐 원래의 데이터 형식으로 언박싱(Unboxing) 해버리기 때문에 오버헤드가 요구되어 성능 저하가 더욱 늘어납니다. 위에서 이야기한 [ ArrayList, Queue, Stack, Hashtable ] 등도 똑같습니다. 이를 해결하기 위해 일반화 컬렉션(Generic Collection)을 사용합니다. (이건 나중에 배워요) 아무튼 ~ 메소드의 사용방법을 알아보시죠.
[다양한 형식의 ArrayList]
public virtual int Add(Object value)
public virtual void Insert(int index, Object value)
[연습]
ArrayList list = new ArrayList();
list.Add(10); //Add : 컬렉션 마지막에 있는 요소 뒤에 새 요소 추가
list.Add(20);
list.Add(30);
list.RemoveAt(1); //1번 삭제(20)
list.Insert(1, 25); //1번 인덱스에 삽입 (10과 30 사이)using System;
using System.Collections;
namespace UsingList
{
class Program
{
static void Main(string[] args)
{
ArrayList list = new ArrayList();
for (int i = 0; i < 5; i++)
list.Add(i);
foreach (object obj in list)
Console.Write($"{obj} ");
Console.WriteLine();
list.RemoveAt(2);
foreach (object obj in list)
Console.Write($"{obj} ");
Console.WriteLine();
list.Insert(2, 99);
foreach (object obj in list)
Console.Write($"{obj} ");
Console.WriteLine();
list.Add("abc");
list.Add("def");
for (int i = 0; i < list.Count; i++)
Console.Write($"{list[i]} ");
Console.WriteLine();
}
}
}[실행 결과]
0 1 2 3 4
0 1 3 4
0 1 99 3 4
0 1 99 3 4 abc def나머지는 다음시간에.