24.01.02 TIL - [C#] 기초 (6) : 배열과 컬렉션

JJwoo·2024년 1월 2일
0

C#

목록 보기
6/20

💿 배열 (Array)

동일한 자료형의 값들이 연속적으로 저장되는 자료 구조

  • 고정된 크기: 배열은 선언 시 정해진 크기를 변경할 수 없다. 이는 배열이 메모리에 연속적으로 할당되기 때문이다.

  • 직접적인 메모리 접근: 배열의 각 요소는 고유한 인덱스를 가지며, 이를 통해 빠른 접근이 가능하다.

  • 동일한 자료형: 배열에 저장되는 모든 요소는 동일한 데이터 유형을 가져야 한다.

🍳 1차원 배열

  • 동일한 데이터 유형을 가지는 데이터 요소들을 한 번에 모아서 다룰 수 있는 구조
  • 인덱스를 사용하여 요소에 접근 가능
  • 선언된 크기만큼의 공간을 메모리에 할당 받음
// 배열 선언
데이터_유형[] 배열_이름;

// 배열 초기화
배열_이름 = new 데이터_유형[크기];

// 배열을 한 줄로 선언 및 초기화
데이터_유형[] 배열_이름 = new 데이터_유형[크기];

// 배열 요소에 접근
배열_이름[인덱스] =;= 배열_이름[인덱스];
예시1)

int[] array1 = new int[5]; // 크기가 5인 int형 배열 선언
string[] array2 = new string[3]; // 크기가 3인 string형 배열 선언
int num = array1[0]; // 배열 첫 번째 요소에 접근
예시2)

int[] array1 = new int[5];       // 크기가 5인 int형 배열 선언
string[] array2 = new string[3]; // 크기가 3인 string형 배열 선언
int num = 0;

// 배열 초기화
array1[0] = 1;
array1[1] = 2;
array1[2] = 3;
array1[3] = 4;
array1[4] = 5;

num = array1[0]; // array1 배열의 첫번째 요소(인덱스 0의 값 1; 을 읽어 num에 저장


아이템 가격 예제)
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");

Length : 배열의 길이, 여기서는 100, 200, 300, 400, 500 이므로 총 5번 반복



게임 캐릭터의 능력치 배열 만들기

            // 플레이어의 공격력, 방어력, 체력, 스피드를 저장할 배열
            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]; // 입력한 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;
                }

            }

        }
}

🧊 다차원 배열

  • 여러 개의 배열을 하나로 묶어 놓은 배열
  • 행과 열로 이루어진 표 형태와 같은 구조
  • 2차원, 3차원 등의 형태의 배열을 의미
  • C#에서는 다차원 배열을 선언할 때 각 차원의 크기를 지정하여 생성합니다.
// 2차원 배열의 선언과 초기화
int[,] array3 = new int[2, 3];  // 2행 3열의 int형 2차원 배열 선언

// 방법1. 다차원 배열 직접 초기화   
// [행, 열]
array3[0, 0] = 1;
array3[0, 1] = 2;
array3[0, 2] = 3;
array3[1, 0] = 4;
array3[1, 1] = 5;
array3[1, 2] = 6;

//방법2. 다차원 배열 for문 초기화
for (int i = 0; i < 2; i++) {
    for (int j = 0; j < 3; j++) {
        array3[i, j] = i + j + 1; // i와 j의 합에 1을 더해 초기화
    }
}



// 선언과 함께 초기화
int[,] array2D = new int[3, 4] { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 } };
// 3차원 배열의 선언과 초기화
int[,,] array3D = new int[2, 3, 4] 
{
    { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 } },
    { { 13, 14, 15, 16 }, { 17, 18, 19, 20 }, { 21, 22, 23, 24 } }
};
int[,] map = new int[5, 5];
for (int i = 0; i < 5; i++)
{
    for (int j = 0; j < 5; j++)
    {
        map[i, j] = i + j;
    }
}

for (int i = 0; i < 5; i++)
{
    for (int j = 0; j < 5; j++)
    {
        Console.Write(map[i, j] + " ");
    }
    Console.WriteLine();
}

6) 2차원 배열을 사용하여 게임 맵을 구현

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();
}

7) 배열을 사용한 숫자 맞추기 게임

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;
    }
}

🍳 다차원 배열의 장점

  • 다차원 배열을 활용하면 복잡한 데이터 구조를 효율적으로 관리할 수 있다.
  • 2차원 배열은 행과 열로 이루어진 데이터 구조를 다루기에 적합하다.
  • 3차원 배열은 면, 행, 열로 이루어진 데이터 구조를 다루기에 적합하다.

📚 컬렉션

자료를 모아놓은 데이터 구조

  • 컬렉션은 배열과 비슷한 자료 구조이지만 배열과는 다르게 크기가 가변적
  • C#에서는 다양한 종류의 컬렉션을 제공
  • 사용하기 위해서는 System.Collections.Generic 네임스페이스를 추가
  • 동적 크기 조정:
    컬렉션은 요소를 추가하거나 제거할 때 크기가 동적으로 조정된다.

  • 다양한 구조 제공:
    List, Dictionary, Stack, Queue:, HashSet 등 다양한 종류의 컬렉션이 존재하며, 각각 특정 상황에 적합하게 사용된다.

  • 유연한 데이터 관리:
    컬렉션은 데이터 추가, 삭제, 검색 등 다양한 작업을 효율적으로 수행할 수 있도록 설계되었다.


1) 리스트 List

-  List는 가변적인 크기를 갖는 배열
-  List에 담을 자료형을 지정하여 생성합니다.
List<int> numbers = new List<int>(); // 빈 리스트 생성

numbers.Add(1); // 리스트에 데이터 추가
numbers.Add(2);
numbers.Add(3);
numbers.Remove(2); // 리스트에서 데이터 삭제

foreach(int number in numbers)//list에 있는 것들을 number에 하나씩 끌어옴, 리스트 데이터 출력
{
    Console.WriteLine(number);
}



for문 표현, 배열과 다르게 Count를 사용)

for(int i=0; i< list.Count; i++)  // length가 아닌 count 사용
{
Console.WriteLine(list[i]);  //list도 [] 인덱싱이 가능
}

배열은 Length, 리스트는 Count


2) 딕셔너리 Dictionary

- 딕셔너리(Dictionary)는 키와 값으로 구성된 데이터를 저장
- 딕셔너리는 중복된 키를 가질 수 없으며, 키`(Key)`와 값`(Value)`의 쌍을 이루어 데이터를 저장
using System.Collections.Generic;

Dictionary<string, int> scores = new Dictionary<string, int>(); // 빈 딕셔너리 생성
scores.Add("Alice", 100); // 딕셔너리에 데이터 추가
scores.Add("Bob", 80);
scores.Add("Charlie", 90);
scores.Remove("Bob"); // 딕셔너리에서 데이터 삭제

foreach(KeyValuePair<string, int> pair in scores) // 딕셔너리 데이터 출력
{
    Console.WriteLine(pair.Key + ": " + pair.Value);
}

KeyValuePair : Key 값과 Value 값을 정해주기 위함, Dictionary와 함께 스인다.


3) 스택 Stack

Stack은 후입선출(LIFO) 구조를 가진 자료 구조로 요소를 저장하고 검색한다.

Stack<int> stack1 = new Stack<int>();  // int형 Stack 선언

// Stack에 요소 추가
stack1.Push(1);
stack1.Push(2);
stack1.Push(3);

// Stack에서 요소 가져오기
int value = stack1.Pop(); // value = 3 (마지막에 추가된 요소)

4) Queue

Queue는 선입선출(FIFO) 구조의 자료 구조.

Queue<int> queue1 = new Queue<int>(); // int형 Queue 선언

// Queue에 요소 추가
queue1.Enqueue(1);
queue1.Enqueue(2);
queue1.Enqueue(3);

// Queue에서 요소 가져오기
int value = queue1.Dequeue(); // value = 1 (가장 먼저 추가된 요소)

5) HashSet

HashSet은 중복되지 않은 요소들로 이루어진 집합

HashSet<int> set1 = new HashSet<int>();  // int형 HashSet 선언

// HashSet에 요소 추가
set1.Add(1);
set1.Add(2);
set1.Add(3);

// HashSet에서 요소 가져오기
foreach (int element in set1)
{
    Console.WriteLine(element);
}

🍳 배열과 컬렉션의 차이

특징배열(Array)컬렉션(Collection)
크기고정된 크기동적으로 크기 조정 가능
메모리 할당선언 시 할당요소 추가/삭제 시 변경
데이터 유형동일한 자료형만 저장다양한 유형의 컬렉션 제공
접근 방식인덱스를 통한 직접 접근다양한 방법(인덱스, 키 등)
사용 사례고정된 데이터 세트유동적인 데이터 세트
성능빠른 데이터 접근데이터 조작 유연성

🥟 배열과 컬렉션의 주요 차이점

  • 메모리 관리: 배열은 정적인 크기를 가지지만, 컬렉션은 동적으로 크기가 조정된다. 따라서 컬렉션은 더 유연하지만, 때로는 추가적인 메모리 오버헤드가 발생할 수 있다.

  • 사용 편의성: 컬렉션은 데이터를 추가하고 제거하기 쉽고, 다양한 유용한 메서드를 제공한다. 반면 배열은 기본적인 데이터 구조이므로, 수동으로 크기 관리와 데이터 조작을 해야 한다.

  • 성능 측면: 배열은 데이터에 대한 접근이 빠르지만, 크기 변경이 불가능하다. 컬렉션은 크기 변경이 가능하지만, 특정 유형의 컬렉션(예: 리스트)에서는 데이터 접근이 배열보다 느릴 수 있다.

배열과 컬렉션 사용 시 고려사항

  • 데이터 크기와 변동성: 고정된 크기의 데이터를 다룰 때는 배열을 사용하는 것이 좋다. 데이터 크기가 자주 변경되거나 다양한 작업을 수행해야 할 때는 컬렉션을 사용하는 것이 유리하다.

  • 성능 요구 사항: 데이터 접근 속도가 중요한 경우 배열이 유리할 수 있다. 다양한 데이터 조작이 필요하거나 크기 조정이 자주 필요한 경우 컬렉션을 고려해야 한다.


🧃 배열과 리스트의 차이

리스트는 동적으로 크기를 조정할 수 있어 배열과는 다르게 유연한 데이터 구조를 구현

  • 1. 메모리 사용량 증가:
    리스트는 동적으로 크기를 조정할 수 있어 배열보다 많은 메모리를 사용합니다. 따라서, 많은 데이터를 다루는 경우 리스트를 무분별하게 사용하면 메모리 사용량이 급격히 증가하여 성능 저하를 유발할 수 있습니다.

  • 2. 데이터 접근 시간 증가:
    리스트는 연결 리스트(linked list)로 구현되기 때문에, 인덱스를 이용한 데이터 접근이 배열보다 느립니다. 리스트에서 특정 인덱스의 데이터를 찾기 위해서는 연결된 노드를 모두 순회해야 하기 때문입니다. 이러한 이유로, 리스트를 무분별하게 사용하면 데이터 접근 시간이 증가하여 성능이 저하될 수 있습니다.

  • 3. 코드 복잡도 증가:
    리스트는 동적으로 크기를 조정할 수 있기 때문에, 데이터 추가, 삭제 등의 작업이 배열보다 간편합니다. 하지만, 이러한 유연성은 코드 복잡도를 증가시킬 수 있습니다. 리스트를 사용할 때는 데이터 추가, 삭제 등의 작업을 적절히 처리하는 코드를 작성해야 하므로, 코드의 가독성과 유지보수성이 저하될 수 있습니다.

데이터의 크기와 사용 목적을 고려하여 배열과 리스트 중 적절한 것을 선택


profile
개발 모코코

0개의 댓글