김김김의 게임개발
  • C# #3 배열과 컬렉션
    2023년 08월 15일 18시 53분 56초에 업로드 된 글입니다.
    작성자: noun06

    배열(Array)

    • 동일한 자료형의 값들이 연속적으로 저장되는 자료 구조.
    • 선언할 때 크기를 지정해야하며, 동적으로 크기 조절이 되지 않음.
    • 인덱스를 통해서 값의 지정, 접근이 가능.
    //배열을 한 줄로 선언 및 초기화
    자료형[] 배열명 = new 자료형[크기];
    
    //배열 요소에 접근
    배열명[인덱스] = 값;
    
    int[] array1 = new int[5]; //크기가 5인 정수형 배열 선언
    string[] array2 = new string[3]; //크기가 3인 문자열 배열 선언
    int num = 0;
    
    array1[0] = 1;
    array1[1] = 2;
    array1[2] = 3;
    array1[3] = 4;
    array1[4] = 5;
    
    num = array1[0];

     

    • 배열의 길이는 배열명.Length.
    int[] itemPrices = new int[5] {10, 20, 30, 40, 50}; //new int[5]는 생략 가능
    //배열 선언 시에도 {값1, 값2}와 같이 값을 지정할 수 있음
    
    int totalPrice = 0;
    
    for(int i = 0; i < itemPrices.Length; i++)
    {
    	totalPrice += itemPrices[i]; //각 인덱스의 값을 모두 더함
    }
    
    Console.WriteLine("아이템들의 총 가격은: " + totalPrice);

     

    1차원 배열 실습

    • 게임 캐릭터의 능력치 배열
    int[] playerStats = new int[4];
    
    Random rand = new Random();
    if(i = 0; i < playerStats.Length; i++)
    {
    	playerStats[i] = rand.Next(1, 11); //능력치를 랜덤으로 생성하여 배열에 저장
    }
    
    Console.WriteLine("공격력: " + playerStats[0] +
                      "\n방어력: " + playerStats[1] +
                      "\n체력: " + playerStats[2] +
                      "\n스피드: " + playerStats[3]);

     

    • 학생들의 성적 평균 구하기
    //평균 성적 구하기
    
    int[] scores = new int [5];
    int sum = 0;
    
    for(int i = 0; i < scores.Length; i++)
    {
    	Console.WriteLine("학생"+ (i+1) +"의 성적을 입력하세요.");
        scores[i] = int.Parse(Console.ReadLine());
        sum += scores[i];
    }
    
    double avgScore = (double)sum / scores.Length; //double형으로 형변환
    Console.WriteLine("평균 성적은: " + avgScore);

     

    • 배열을 활용한 숫자 맞추기 게임
    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차원 배열

    • 여러 개의 배열을 하나로 묶어 놓은 배열.
    • 행렬(Matrix)로 이루어진 표 형태의 구조.
    • 2차원 배열에서 요소에 접근할 때는 [행, 열]의 인덱스를 사용.
    • 보통 2차원 배열을 다룰 때 행과 열을 모두 순회하여 배열의 각 요소에 접근하고 처리하기 위해 이중반복문을 사용하는 경우가 많음. (i : 행, j : 열)
    // 2x3 크기의 2차원 배열 선언 및 초기화
    int[,] matrix = new int[2, 3] {
        { 1, 2, 3 },
        { 4, 5, 6 }
    };
    
    int element = matrix[1,2]; //2행 3열의 요소(값 : 6)

     

    2차원 배열 실습

    • 2차원 맵 만들기
    int[,] map = new int[5, 5] //2차원 배열 선언
    { 
        { 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();
    }

     

    컬렉션

    • 데이터를 저장하고 관리하기 위한 자료 구조의 일종.
    • 여러 개의 항목을 하나의 단위로 묶어서 다루는 방법을 제공하며 배열과 다르게 크기가 가변적.
    • 컬렉션의 길이는 변수명.Count.

     

    • List : 가변적인 크기를 가지며 순차적으로 데이터를 저장.(중복된 값 허용, 인덱스를 사용하여 접근)
    List<자료형> 변수명 = new List<자료형>();
    
    List<int> numbers = new List<int>();
    numbers.Add(1); // 리스트에 데이터 추가
    numbers.Add(2);
    numbers.Add(3);
    numbers.Remove(2); // 리스트에서 데이터 삭제
    
    bool contains1 = numbers.Contains(1); // true 반환
    
    foreach(int number in numbers) // 리스트 데이터 출력
    {
        Console.WriteLine(number);
    }

     

    • Dictionary : 키와 값으로 구성된 데이터를 저장.(키와 값의 쌍을 이루며 키는 고유해야 함)
    Dictionary<키, 값> 변수명 = new Dictionary<키, 값>();
    
    Dictionary<string, int> scores = new Dictionary<string, int>(); // 빈 딕셔너리 생성
    scores.Add("Alice", 100); // 딕셔너리에 데이터 추가
    scores.Add("Bob", 80);
    scores.Add("Charlie", 90);
    scores.Remove("Bob"); // 딕셔너리에서 데이터 삭제
    
    bool containsAlice = scores.ContainsKey("Alice"); // true 반환
    //ConstainsKey()를 통해 특정 키가 있는지 확인
    
    foreach(KeyValuePair<string, int> pair in scores) // 딕셔너리 데이터 출력
    {
        Console.WriteLine(pair.Key + ": " + pair.Value);
    }

     

     

    • Stack : 후입선출(LIFO) 구조를 가진 컬렉션. 메모리의 함수 호출 스택 등에 사용되며 역순으로 데이터 처리 시 활용.
    Stack<자료형> 변수명 = new Stack<자료형>();
    
    Stack<int> stack1 = new Stack<int>();  // int형 Stack 선언
    
    // Stack에 요소 추가
    stack1.Push(1);
    stack1.Push(2);
    stack1.Push(3);
    
    // Stack에서 요소 가져오기
    int value = stack1.Pop(); // 스택의 가장 위 데이터 3을 반환하고 제거.
    
    int value = stack1.Peek(); // 스택의 가장 위 데이터 2를 반환하지만 제거하지 않음.

     

    • Queue : 선입선출(FIFO) 구조를 가진 컬렉션. 작업 대기열, 태스크 처리 등에 사용, 순차적 데이터 처리에 활용.
    Queue<자료형> 변수명 = new Queue<자료형>();
    
    Queue<int> queue1 = new Queue<int>(); // int형 Queue 선언
    
    // Queue에 요소 추가
    queue1.Enqueue(1);
    queue1.Enqueue(2);
    queue1.Enqueue(3);
    
    // Queue에서 요소 가져오기
    int value = queue1.Dequeue(); // 큐의 가장 먼저 추가된 데이터 1을 반환하고 제거.
    
    int value = queue1.Peek(); // 큐의 가장 먼저 추가된 데이터 1을 반환하고 제거하지 않음.

     

    • HashSet : 중복된 값을 허용하지 않는 컬렉션. 중복을 제거하거나 고유한 값만 저장할 때 사용.
    HashSet<자료형> 변수명 = new HashSet<자료형>();
    
    HashSet<int> set1 = new HashSet<int>();  // int형 HashSet 선언
    
    // HashSet에 요소 추가
    set1.Add(1);
    set1.Add(2);
    set1.Add(3);
    
    //HashSet에 요소 제거
    bool removedOne = set1.Remove(1); //true 반환, 1 제거
    
    //HashSet에 요소 검색
    bool containsTwo = set1.Contains(2); //2 반환
    
    // HashSet에서 요소 가져오기
    foreach (int element in set1)
    {
        Console.WriteLine(element);
    }
    
    //집합연산
    ...

     

    배열과 리스트

    • 리스트는 동적으로 크기를 조정할 수 있어 배열보다 많은 메모리를 사용하므로 무분별한 사용 주의.
    • 리스트는 연결 리스트(linked list)로 구현되므로 인덱스를 이용한 데이터 접근이 배열보다 느림.
    • 리스트에서는 데이터 추가, 삭제 작업이 간편하지만 이로 인해 코드 복잡도가 증가할 수 있음.

     

    오늘은 배열과 반복문의 활용과 다양한 컬렉션들을 간단하게 알아보았습니다. 각 컬렉션들이 주로 어떠한 상황에 사용되는지 더 알아보았고 이후에 자료구조 파트에서 더 깊게 공부할 예정입니다. 

     

    댓글