📘 배열과 컬렉션
배열
1차원 배열
동일한 데이터 유형을 연속적으로 저장하며, 인덱스를 통해 요소에 접근할 수 있다. 배열은 선언 시 고정된 크기를 가지며, 크기 이상의 데이터는 저장할 수 없다.
int[] array1 = new int[5];
array1[0] = 1;
...
...
예제: 배열을 활용한 합계 계산
int[] itemPrices = { 100, 200, 300, 400, 500 };
int totalPrice = 0;
for (int i = 0; i < itemPrices.Length; i++)
{
totalPrice += itemPrices[i];
}
Console.WriteLine("총 아이템 가격: " + totalPrice + " gold");
배열 실습 예시
- 게임 캐릭터 능력치 배열
- 학생 성적 평균 계산
- 배열 기반 숫자 맞추기 게임
다차원 배열
행과 열로 구성된 2차원 이상의 배열 구조로, 표 형태의 데이터를 처리할 때 사용된다.
int[,] array2D = new int[2, 3];
int[,,] array3D = new int[2, 3, 4];
예제: 2차원 배열을 활용한 게임 맵
int[,] map = {
{1,1,1,1,1},
{1,0,0,0,1},
...
};
컬렉션
컬렉션은 배열과 유사하지만, 크기가 가변적이며 다양한 기능을 지원하는 자료 구조다. C#의 컬렉션은 System.Collections.Generic 네임스페이스에 정의되어 있다.
List
동적으로 크기가 조정되는 배열 구조로, 요소의 추가/삭제/삽입이 가능하다. 내부적으로 배열을 기반으로 동작하며, 요소가 많아질 경우 새로운 배열을 생성해 데이터를 복사하는 방식으로 확장된다.
List<int> numbers = new List<int>();
numbers.Add(1); numbers.Remove(1);
Dictionary
키와 값의 쌍으로 데이터를 저장하는 구조다. 키는 중복될 수 없으며, 값에 빠르게 접근할 수 있는 장점이 있다.
Dictionary<string, int> scores = new Dictionary<string, int>();
scores.Add("Alice", 100);
Stack
후입선출(LIFO) 구조로 동작하며, Push()로 추가하고 Pop()으로 제거한다.
Stack<int> stack = new Stack<int>();
stack.Push(1); int val = stack.Pop();
Queue
선입선출(FIFO) 구조로 동작하며, Enqueue()로 추가하고 Dequeue()로 제거한다.
Queue<int> queue = new Queue<int>();
queue.Enqueue(1); int val = queue.Dequeue();
HashSet
중복을 허용하지 않는 집합 구조다. 삽입 순서가 보장되지 않으며, Contains()로 존재 여부를 확인할 수 있다.
HashSet<int> set = new HashSet<int>();
set.Add(1); set.Contains(1);
배열 vs 리스트
항목 |
배열 |
리스트 |
크기 |
고정 |
가변 |
메모리 |
정적 할당 |
동적 배열 구조 |
기능 |
단순 저장/접근 |
삽입, 삭제, 탐색 등 다양 |
성능 |
반복에 유리 |
유연성 뛰어남 |
- 데이터 크기가 고정되거나 반복 연산 중심일 경우 배열 사용이 유리하다.
- 유동적인 데이터 처리, 삽입/삭제가 잦은 경우 리스트를 사용하는 것이 효율적이다.
게임케릭터 능력치 만들기
// 플레이어의 공격력, 방어력, 체력, 스피드를 저장할 배열
int[] playerStats = new int[4];
// 능력치를 랜덤으로 생성하여 배열에 저장
Random rand = new Random();
for (int i = 0; i < playerStats.Length; i++)
{
playerStats[i] = rand.Next(1, 11);
}
// 능력치 출력
Console.WriteLine("플레이어의 공격력: " + playerStats[0]);
Console.WriteLine("플레이어의 방어력: " + playerStats[1]);
Console.WriteLine("플레이어의 체력: " + playerStats[2]);
Console.WriteLine("플레이어의 스피드: " + playerStats[3]);
학생들의 성적 평균 구하기
int[] scores = new int[5]; // 5명의 학생 성적을 저장할 배열
// 성적 입력 받기
for (int i = 0; i < scores.Length; i++)
{
Console.Write("학생 " + (i + 1) + "의 성적을 입력하세요: ");
scores[i] = int.Parse(Console.ReadLine());
}
// 성적 총합 계산
int sum = 0;
for (int i = 0; i < scores.Length; i++)
{
sum += scores[i];
}
// 성적 평균 출력
double average = (double)sum / scores.Length;
Console.WriteLine("성적 평균은 " + average + "입니다.");
배열을 활용한 숫자 맞추기 게임
Random random = new Random(); // 랜덤 객체 생성
int[] numbers = new int[3]; // 3개의 숫자를 저장할 배열
// 3개의 랜덤 숫자 생성하여 배열에 저장
for (int i = 0; i < numbers.Length; i++)
{
numbers[i] = random.Next(1, 10);
}
int attempt = 0; // 시도 횟수 초기화
while (true)
{
Console.Write("3개의 숫자를 입력하세요 (1~9): ");
int[] guesses = new int[3]; // 사용자가 입력한 숫자를 저장할 배열
// 사용자가 입력한 숫자 배열에 저장
for (int i = 0; i < guesses.Length; i++)
{
guesses[i] = int.Parse(Console.ReadLine());
}
int correct = 0; // 맞춘 숫자의 개수 초기화
// 숫자 비교 및 맞춘 개수 계산
for (int i = 0; i < numbers.Length; i++)
{
for (int j = 0; j < guesses.Length; j++)
{
if (numbers[i] == guesses[j])
{
correct++;
break;
}
}
}
attempt++; // 시도 횟수 증가
Console.WriteLine("시도 #" + attempt + ": " + correct + "개의 숫자를 맞추셨습니다.");
// 모든 숫자를 맞춘 경우 게임 종료
if (correct == 3)
{
Console.WriteLine("축하합니다! 모든 숫자를 맞추셨습니다.");
break;
}
}
게임 맵을 구현
int[,] map = new int[5, 5]
{
{ 1, 1, 1, 1, 1 },
{ 1, 0, 0, 0, 1 },
{ 1, 0, 1, 0, 1 },
{ 1, 0, 0, 0, 1 },
{ 1, 1, 1, 1, 1 }
};
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 5; j++)
{
if (map[i, j] == 1)
{
Console.Write("■ ");
}
else
{
Console.Write("□ ");
}
}
Console.WriteLine();
}