C# - 스택/큐 실습 문제 풀이

2025. 9. 26. 18:54·C#

과제

Milk라는 클래스와 VendingMachine 이라는 클래스를 하나 만들겠습니다. Milk의 맴버변수로, 유통기한을 나타내는 int를 작성해주시기 바랍니다.

VendingMachine 클래스에는 Queue를 활용하여 Milk를 담을 수 있는 컨테이너를 필드로 작성하여 주시기 바랍니다.

벤딩머신의 메소드로, 우유를 집어넣는 코드와 우유를 꺼내는 기능을 작성하되, 꺼낼때는 콘솔에 유통기한 및 큐에 남아있는 갯수를 출력하는 기능을 작성해주시기 바랍니다. 갯수가 0일때 우유를 꺼내는 기능을 호출하게 되면 꺼내는 대신 다른 멘트가 나오게끔 작성해주시길 바랍니다.

 

 

Milk.cs

using System;

namespace StackQueue
{
    class Milk
    {
        public int ExpireAt { get; private set; }
        public string Name { get; private set; }

        public Milk(string inputName, int inputExpire)
        {
            Name = inputName;
            ExpireAt = inputExpire;
        }
    }
}

 

 

VendingMachine.cs

using System;
using System.Collections.Generic;

namespace StackQueue
{
    class VendingMachine
    {
        Queue<Milk> milkContainer = new Queue<Milk>();

        // 우유 넣기 메서드
        public void AddMilk(Milk milk)
        {
            milkContainer.Enqueue(milk);
            Console.WriteLine($"머신에 넣은 우유: {milk.Name} / 유통기한 : {milk.ExpireAt}");
        }

        // 우유 꺼내기 메서드
        public void RemoveMilk()
        {
            if ( milkContainer.Count > 0 )
            {
                Milk dequeuedMilk = milkContainer.Dequeue();
                Console.WriteLine($"꺼낸 우유 : {dequeuedMilk.Name} / {dequeuedMilk.ExpireAt}");
                Console.WriteLine("-------------------------------------------");
                Console.WriteLine($"남아있는 우유 갯수: {milkContainer.Count}");
                foreach ( Milk milk in milkContainer )
                {
                    Console.WriteLine($"{milk.Name} 의 유통기한 : {milk.ExpireAt}");
                }
                Console.WriteLine("-------------------------------------------");
                Console.WriteLine();
            }
            else
            {
                Console.WriteLine();
                Console.WriteLine("남아있는 우유가 없소...");
                Console.WriteLine();
            }
        }
    }
}

 

 

Program.cs

using System;

namespace StackQueue
{
    class Program
    {
        static void Main(string[] args)
        {
            VendingMachine machine = new VendingMachine();

            Console.WriteLine();
            Console.WriteLine("----------- 우유 넣기 테스트 -----------");
            Console.WriteLine();

            machine.AddMilk(new Milk("1번 우유", 25092424));
            machine.AddMilk(new Milk("2번 우유", 25092512));
            machine.AddMilk(new Milk("3번 우유", 25092622));
            machine.AddMilk(new Milk("4번 우유", 25092703));
            machine.AddMilk(new Milk("5번 우유", 25092800));

            Console.WriteLine();
            Console.WriteLine("----------- 우유 꺼내기 테스트 -----------");
            Console.WriteLine();

            machine.RemoveMilk();
            machine.RemoveMilk();
            machine.RemoveMilk();
            machine.RemoveMilk();
            machine.RemoveMilk();
            machine.RemoveMilk();
            machine.RemoveMilk();
        }
    }
}

 

 

 

 

 

큐를 이용해 우유가 들어간 순서대로 빠져나오는 것이 정상 동작하는 걸 확인할 수 있었다.

 

 

 


 

자가진단 심화 과제 ) 본인이 판단하는 자료구조

Shape라는 Enum을 만들어서 Spade, Heart, Clover, Diamond 네 가지를 요소로 가지게 합니다.

Card라는 클래스를 만듭니다. 위 열거형을 Card클래스 맴버변수로 가지게 해주세요. Card클래스에는 숫자를 나타내는 int형을 넣되, a는 1, J는 11, Q는 12, K는 13이라고 가정하겠습니다.

CardDeck이라는 클래스도 하나 제작하도록 하겠습니다. Card 객체를 52개 담을 수 있는 ???(자료구조) 들을 활용하여 두 개 만드시되, 하나는 unusedCards, 하나는 usedCards 의 이름으로 만들겠습니다.

CardDeck 클래스의 생성자에 unusedCards 속 52개의 Card를 중복없이 뉴할당해서 넣어주는 코드를 작성하여 주시기 바랍니다. 카드를 섞는 메소드를 작성하거나 생성자에서 바로 진행해주시기 바랍니다.

CardDeck 클래스에 아직 쓰지 않은 맨 위 카드를 보기만 하는 ShowTopCard 기능을 제작하여 주시기 바랍니다. 이는 맨 상단의 카드를 보기만 할 뿐 카드를 소모하진 않습니다. DrawCard라는 메소드도 하나 제작하겠습니다. 이 메소드는 아직 쓰지 않은 덱의 맨 위 카드를 반환받고 그와 동시에 usedCard에 쌓는 기능을 수행합니다.

 

 

Card.cs

using System;

namespace StackQueue
{
    enum Shape
    {
        Spade, Heart, Clover, Diamond
    }

    class Card
    {
        public Shape Shape { get; private set; }
        public int CardNum { get; private set; }

        public Card(Shape inputShape, int inputNum)
        {
            Shape = inputShape;
            CardNum = inputNum;
            //Console.WriteLine($"{Shape} {CardNum} 카드 생성");
        }
    }
}

 

 

CardDeck.cs

using System;
using System.Collections.Generic;
using System.Linq;

namespace StackQueue
{
    class CardDeck
    {
        Stack<Card> unusedCards = new Stack<Card>();
        Stack<Card> usedCards = new Stack<Card>();

        public CardDeck()
        {            
            // 각 Shape x 12 카드 생성
            // 이거 GetValues 런타임 중에 생각보다 무겁다 함. enum 끝에 End 두면 그게 Length값 ㄷㄷ
            for (int i = 0; i < Enum.GetValues(typeof(Shape)).Length; i++)
            {
                for (int j = 1; j <= 13; j++)
                {
                    unusedCards.Push(new Card((Shape)i, j));
                }
            }

            // 생성된 카드 셔플
            CardShuffle();
            Console.WriteLine("카드 생성 및 셔플 완료");
        }

        public void ShowTopCard()
        {
            Console.WriteLine($"확인한 맨 위 카드: {unusedCards.Peek().Shape} {unusedCards.Peek().CardNum}");
        }

        public void DrawCard()
        {
            // unUserCards 맨 위 카드 빼고, usedCard에 쌓아
            Card popedCard = unusedCards.Pop();
            Console.WriteLine($"드로우 한 카드 : {popedCard.Shape} {popedCard.CardNum}");
            usedCards.Push(popedCard);
        }

        // 카드 셔플 메서드
        public void CardShuffle()
        {
            // 리스트로 변환
            List<Card> cards = unusedCards.ToList();
            Random rnd = new Random();

            // 모든 카드를 랜덤한 위치와 자리 변경
            for (int i = 0; i < cards.Count; i++)
            {
                int tempRnd = rnd.Next(0, cards.Count);
                Card tempCard = cards[i];
                cards[i] = cards[tempRnd];
                cards[tempRnd] = tempCard;
            }

            // 덱에 적용
            unusedCards = new Stack<Card>(cards.Reverse<Card>());
        }


        // 테스트를 위한 덱 전체 열람 메서드
        public void ShowAllUnUsedCards()
        {
            Console.WriteLine();
            Console.WriteLine($"-------------- 미열람 카드 전체 리스트 {unusedCards.Count} --------------");
            foreach (Card card in unusedCards)
            {
                Console.WriteLine($"{card.Shape} {card.CardNum}");
            }
            Console.WriteLine("--------------------------------------------------");
            Console.WriteLine();
        }

        public void ShowAllUsedCards()
        {
            Console.WriteLine();
            Console.WriteLine($"-------------- 미열람 카드 전체 리스트 {usedCards.Count} --------------");
            foreach (Card card in usedCards)
            {
                Console.WriteLine($"{card.Shape} {card.CardNum}");
            }
            Console.WriteLine("--------------------------------------------------");
            Console.WriteLine();
        }
    }
}

 

 

Program.cs

using System;

namespace StackQueue
{
    class Program
    {
        static void Main(string[] args)
        {
            CardDeck cardDeck = new CardDeck();

            // 미열람 카드 조회
            cardDeck.ShowAllUnUsedCards();

            // 픽, 드로우 테스트
            cardDeck.ShowTopCard();
            cardDeck.DrawCard();
            cardDeck.ShowTopCard();
            cardDeck.DrawCard();
            cardDeck.ShowTopCard();
            cardDeck.DrawCard();
            cardDeck.DrawCard();
            cardDeck.DrawCard();
            cardDeck.DrawCard();
            cardDeck.DrawCard();

            // 열람 카드 조회
            cardDeck.ShowAllUsedCards();

            // 미열람 카드 조회
            cardDeck.ShowAllUnUsedCards();
        }
    }
}

 

 

 

 

 

의도한대로 잘 동작한다.

여기서 몇가지만 더 보고 가자

 

public void CardShuffle()
{
    // 리스트로 변환
    List<Card> cards = unusedCards.ToList();
    Random rnd = new Random();

    // 모든 카드를 랜덤한 위치와 자리 변경
    for (int i = 0; i < cards.Count; i++)
    {
        int tempRnd = rnd.Next(0, cards.Count);
        Card tempCard = cards[i];
        cards[i] = cards[tempRnd];
        cards[tempRnd] = tempCard;
    }

    // 덱에 적용
    unusedCards = new Stack<Card>(cards.Reverse<Card>());
}

 

이 셔플 메서드는

cards 수 만큼 순환하면서 인덱스 i와, 랜덤 인덱스의 카드를 스왑시키는 코드다.

피셔예이츠와 비슷한데, 피셔예이츠에서는 균등한 분배를 위한 처리가 되어있으나, 오히려 이 편이 조금 더 현실적인 셔플에 가깝다 생각해서 이렇게 구현했다.

 

그리고 CardDeck.cs 쪽의

public CardDeck()
{            
    // 각 Shape x 12 카드 생성
    for (int i = 0; i < (int)Shape.End; i++)
    {
        for (int j = 1; j <= 13; j++)
        {
            unusedCards.Push(new Card((Shape)i, j));
        }
    }

    // 생성된 카드 셔플
    CardShuffle();
    Console.WriteLine("카드 생성 및 셔플 완료");
}

 

이 생성자 코드를 보면 Enum.GetValues(typeof(Shape)) 으로 Shape이 추가되는 상황에도 대응할 수 있게 작성했다.

하지만 GetValues는 런타임 도중에 작동하기에 다소 무거울 수 있어 더욱 최적화를 진행해봤다.

 

enum Shape
{
    Spade, Heart, Clover, Diamond, End // End를 끝에 추가
}

 

열거형을 이렇게 구성하면 End 값이 Shape의 Length에 해당하는 값이 된다.

 

for (int i = 0; i < (int)Shape.End; i++)

 

for문을 이렇게 수정하는 것으로 최적화 할 수 있다.

Enum 값에 시작, 끝에 특정 값을 정의하는 것으로 이런 활용이 가능하다는 아이디어가 인상 깊었다.

'C#' 카테고리의 다른 글

C# - 자료구조 : 트리 (Tree) & 그래프 (Graph)  (1) 2025.09.29
C# - 덱 (Deque : Double Ended Queue)  (0) 2025.09.29
C# - 딕셔너리 (Dictionary)  (0) 2025.09.26
C# - 스택 (Stack), 큐 (Queue)  (0) 2025.09.26
C# - BFS (너비 우선 탐색) / DFS (깊이 우선 탐색)  (0) 2025.09.25
'C#' 카테고리의 다른 글
  • C# - 자료구조 : 트리 (Tree) & 그래프 (Graph)
  • C# - 덱 (Deque : Double Ended Queue)
  • C# - 딕셔너리 (Dictionary)
  • C# - 스택 (Stack), 큐 (Queue)
ellug
ellug
Web / App / Game Dev
  • ellug
    dev.ellug
    ellug
  • 전체
    오늘
    어제
    • 분류 전체보기 (95)
      • Javascript (React, Next) (1)
      • C# (66)
      • Graphics (1)
      • Unity (25)
      • 프로그래머스 (0)
        • Lv.0 (0)
        • Lv.1 (0)
        • Lv.2 (0)
        • Lv.3 (0)
      • AI Agent (0)
      • StableDiffusion (0)
      • ETC (1)
      • 잡담 (0)
      • 유머 (0)
  • 블로그 메뉴

    • 홈
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    Abstract
    C#
    class
    function
    유니티
    useState
    추상 클래스
    자료구조
    Design Pattern
    Network
    list
    알고리즘
    delegate
    큐
    console
    스택
    콘솔
    struct
    네트워크
    Queue
    터미널
    firebase
    stack
    클래스
    unity
    Photon
    최적화
    inputsystem
    interface
    게임
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.4
ellug
C# - 스택/큐 실습 문제 풀이
상단으로

티스토리툴바