뇌를 자극하는 C# 4.0 프로그래밍/ 배열과 컬렉션, 그리고 인덱서

All for one, one for all

// 배열 선언 방법
데이터형식[] 배열이름 = new 데이터형식[용량];
  • 배열은 같은 타입의 변수 여러 개를 한 번에 다룰 수 있기 때문에 편리하고 가독성도 좋다.

배열을 초기화하는 방법 세 가지

// 배열의 용량을 명시
string[] array1 = new string[3]{ "안녕", "hello", "halo" };

// 배열의 용량을 생략
string[] array2 = new string[]{ "안녕", "hello", "halo" };

// 데이터를 대입
string[] array2 = { "안녕", "hello", "halo" };

알아 두면 삶이 윤택해지는 System.Array

분류 이름 설명
정적 메소드 Sort() 배열을 정렬
정적 메소드 BinarySearch() 이진 탐색을 수행
정적 메소드 IndexOf() 배열에서 찾고자 하는 특정 데이터의 인덱스를 반환
정적 메소드 TrueForAll() 배열의 모든 요소가 지정한 조건에 부합하는지 여부를 반환
정적 메소드 FindIndex() 배열에서 지정한 조건에 부합하는 첫 번째 요소의 인덱스를 반환. IndexOf()가 특정 값을 찾는데 비해, FindIndex()는 지정한 조건에 바탕하여 값을 찾는다.
정적 메소드 Resize() 배열의 크기를 재조정
정적 메소드 Clear() 배열의 모든 요소를 초기화
정적 메소드 ForEach() 배열의 모든 요소에 대해 동일한 작업을 수행
인스턴스 메소드 GetLength() 배열에서 지정한 차원의 길이를 반환
프로퍼티 Length 배열의 길이를 반환
프로퍼티 Rank 배열의 차원을 반환

2차원 배열

// 2차원 배열 선언 방법
데이터형식[ , ] 배열이름 = new 데이터형식[2차원길이, 1차원길이];

// 2차원 배열 초기화 방법
// 배열의 형식과 길이를 명시
int[,] arr = new int[2, 3]{ { 1, 2, 3 }, { 4, 5, 6 } };

// 배열의 길이를 생략
int[,] arr = new int[,]{ { 1, 2, 3 }, { 4, 5, 6 } };

// 데이터를 대입
int[,] arr = { { 1, 2, 3 }, { 4, 5, 6 } };

다차원 배열

// 다차원 배열 선언 예시
int[, ,] array = new int[4, 3, 2]
{
    { { 1, 2 }, { 3, 4 }, { 5, 6 } },
    { { 1, 4 }, { 2, 5 }, { 3, 6 } },
    { { 6, 5 }, { 4, 3 }, { 2, 1 } },
    { { 6, 3 }, { 5, 2 }, { 4, 1 } },
}
  • 3차원 이상의 다차원 배열은 가능하면 쓰지 말자.

가변 배열

// 가변 배열 선언 방법
데이터형식[][] 배열이름 = new 데이터형식[가변배열의 용량][];

// 선언 예시
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 };
  • 가변 배열의 요소로 입력되는 배열은 그 길이가 모두 같을 필요가 없다. 그래서 가변배열 –들쭉날쭉한– 이라고 부른다.
  • 가변 배열은 다차원 배열과 달리 배열을 요소로써 접근할 수 있다.

컬렉션 맛보기

ArrayList

// ArrayList 사용 예시
ArrayList list = new ArrayList();
list.Add(10);
list.Add(20);
list.Add(30);

list.RemoveAt(1); // 20을 삭제

list.Insert(25, 1) // 25를 1번 인덱스에 삽입

Queue

// Queue 사용 예시
Queue que = new Queue();
que.Enqueue(1);
que.Enqueue(2);
que.Enqueue(3);

int a = que.Dequeue(); // 제일 앞에 있는 1이 빠져서 a에 대입된다.
  • Queue는 작업을 차례대로 입력해 뒀다가 입력된 순서대로 하나씩 꺼내 처리하는 자료 구조이다.
  • 배열이나 리스트가 원하는 위치에 자유롭게 접근하는 반면 Queue는 입력은 오로지 뒤에서, 출력은 오로지 앞에서만 이루어진다.
    • Queue는 OS에서 CPU가 처리해야 할 작업을 정리할 때, 프린터가 여러 문서를 출력할 때, 인터넷 동영상 스트리밍 서비스에서 컨텐츠를 버퍼링할 때 등과 같은 많은 곳에서 사용되는 자료 구조이다.

Stack

// Stack 사용 예시
Stack stack = new Stack();
stack.Push(1); // 최상위 데이터는 1
stack.Push(2); // 최상위 데이터는 2
stack.Push(3); // 최상위 데이터는 3

int a = stack.Pop(); // 제일 위에 있는 3이 빠져서 a에 대입되고 최상위 데이터는 2가 됨.
  • Stack은 Queue와 반대로 먼저 들어온 데이터가 나중에 나가고(First In-Last Out), 나중에 들어온 데이터는 먼저 나가는(Last In-First Out) 자료 구조이다.

Hashtable

// Hashtable 사용 예시
Hashtable ht = new Hashtable();
ht["book"] = "책";
ht["cook"] = "요리사";
ht["tweet"] = "지저귐";

Console.WriteLine( ht["book"] );
Console.WriteLine( ht["cook"] );
Console.WriteLine( ht["tweet"] );
  • Hashtable은 키(key)와 값(value)의 쌍으로 이루어진 데이터를 다룰 때 사용한다. ex) 사전
  • Hashtable은 탐색 속도도 빠르고 사용하는 것도 편리하다.

인덱서

// indexer 선언 방법
class 클래스 이름
{
    한정자 인덱서형식 this[형식 index]
    {
        get
        {
            // index를 이용하여 내부 데이터 반환
        }
        set
        {
            // index를 이용하여 내부 데이터 저장
        }
    }
}

// indexer 사용 예시
class MyList
{
    public int[] array;

    public MyList()
    {
        array new int[3];
    }

    public int this[int index]
    {
        get
        {
            return array[index];
        }
        set
        {
            if (index >= array.Length)
            {
                Array.Resize<int>(ref array, index+1);
                Console.WriteLine("Array Resized: {0}", array.Length);
            }

            array[index] = value;
        }
    }
}
  • 인덱서는 인덱스를 이용해서 객체 내의 데이터에 접근하게 해주는 프로퍼티와 같다. 프로퍼티가 이름을 통해 객체 내의 데이터에 접근하게 해 준다면, 인덱서는 인덱스를 통해 객체 내의 데이터에 접근하게 해준다.
  • (추가) static 클래스는 객체를 만들 수 없기 때문에 this 키워드를 사용할 수 없다. 따라서 static 클래스에서는 인덱서를 사용할 수 없다.

foreach가 가능한 객체를 만들어 보자

  • foreach 구문은 IEnumerable과 IEnumerator를 상속하는 형식만 지원한다.
    • IEnumerable과 IEnumerator의 메소드와 프로퍼티는 아래에 표로 정리
  • (실제 객체 만드는 예시는 생략)

IEnumerable의 메소드

메소드 설명
IEnumerator GetEnumerator() IEnumerator 형식의 객체를 반환

IEnumerator의 메소드와 프로퍼티

메소드 설명
boolean MoveNext() 다음 요소로 이동. 컬렉션의 끝을 지난 경우에는 false, 이동이 성공한 경우에는 true를 반환한다.
void Reset() 컬렉션의 첫 번째 위치의 “앞”으로 이동. 첫 번째 위치가 0번 이라면 Reset()을 호출하면 -1로 이동하게 된다. 첫 번째 위치로의 이동은 MoveNext()를 호출한 다음에 이루어진다.
Object Current { get; } 컬렉션의 현재 요소를 반환한다.
It's only fair to share...Share on FacebookShare on Google+Tweet about this on TwitterShare on LinkedIn

The author

지성을 추구하는 디자이너/ suyeongpark@abyne.com

댓글 남기기