자료구조, 코딩테스트/스택(Stack)

[코딩테스트] BOJ 10828 - 스택 (성공)

RꞮbble 2026. 4. 9. 12:04

 

https://www.acmicpc.net/problem/10828

 

 

문제

정수를 저장하는 스택을 구현한 다음, 입력으로 주어지는 명령을 처리하는 프로그램을 작성하시오.

명령은 총 다섯 가지이다.

  • push X: 정수 X를 스택에 넣는 연산이다.
  • pop: 스택에서 가장 위에 있는 정수를 빼고, 그 수를 출력한다. 만약 스택에 들어있는 정수가 없는 경우에는 -1을 출력한다.
  • size: 스택에 들어있는 정수의 개수를 출력한다.
  • empty: 스택이 비어있으면 1, 아니면 0을 출력한다.
  • top: 스택의 가장 위에 있는 정수를 출력한다. 만약 스택에 들어있는 정수가 없는 경우에는 -1을 출력한다.

 

 

입력

첫째 줄에 주어지는 명령의 수 N (1 ≤ N ≤ 10,000)이 주어진다. 둘째 줄부터 N개의 줄에는 명령이 하나씩 주어진다. 주어지는 정수는 1보다 크거나 같고, 100,000보다 작거나 같다. 문제에 나와있지 않은 명령이 주어지는 경우는 없다.

 

 

출력

출력해야하는 명령이 주어질 때마다, 한 줄에 하나씩 출력한다.

 

 

예제 입력1

14
push 1
push 2
top
size
empty
pop
pop
pop
size
empty
pop
push 3
empty
top

 

예제 출력1

2
2
0
2
1
-1
0
1
-1
0
3

 

 

예제 입력2

7
pop
top
push 123
top
pop
top
pop

 

예제 출력2

-1
-1
123
123
-1
-1

 

 

풀이

Collection.Generic에 있는 Stack를 사용해도 되고, 직접 큐를 구현해서 풀어도 되겠다.

 

직접 구현 코드

internal class BOJ10828_스택
{
    public const int MAX = 10000;
    public static int[] dataArray = new int[MAX];
    public static int pos = 0;

    public static StreamWriter sw = new StreamWriter(Console.OpenStandardOutput());
    public static StreamReader sr = new StreamReader(Console.OpenStandardInput());

    public static void Push(int value)
    {
        dataArray[pos++] = value;
    }

    public static void Pop()
    {
        // 가장 위에 있는 수 출력
        Top();

        if(!IsEmpty())
            pos--;
    }

    public static void Top()
    {
        if (IsEmpty())
            sw.WriteLine(-1);
        else
            sw.WriteLine(dataArray[pos - 1]);
    }

    public static bool IsEmpty()
    {
        if (pos == 0)
            return true;
        else
            return false;
    }

    public static void Empty()
    {
        if (pos == 0)
            sw.WriteLine(1);
        else
            sw.WriteLine(0);
    }

    public static void Size()
    {
        sw.WriteLine(pos);
    }

    static void Main(string[] args)
    {
        // Stack 사용한 풀이 

        // Stack 직접 구현한 풀이 
        int N = int.Parse(sr.ReadLine());

        string[] input;
        int value = 0;
        for(int i = 0; i < N; i++)
        {
            input = sr.ReadLine().Split(" ");

            if (input[0] == "push")
            {
                value = int.Parse(input[1]);

                Push(value);
            }
            else if (input[0] == "top")
            {
                Top();
            }
            else if (input[0] == "size")
            {
                Size();
            }
            else if (input[0] == "empty")
            {
                Empty();
            }
            else if (input[0] == "pop")
            {
                Pop();
            }
        }

        sw.Close();
        sr.Close();
    }
}

 

Collection.Generic.Stack 사용 코드

internal class BOJ10828_스택_컬렉션_사용
{
    public static void Main(string[] args)
    {
        StreamReader sr = new StreamReader(Console.OpenStandardInput());
        StreamWriter sw = new StreamWriter(Console.OpenStandardOutput());

        Stack<int> stack = new Stack<int>();

        int N = int.Parse(sr.ReadLine());

        string[] input;
        int value = 0;
        for(int i = 0; i < N; i++)
        {
            input = sr.ReadLine().Split(" ");

            if (input[0] == "push")
            {
                value = int.Parse(input[1]);
                stack.Push(value);
            }
            else if (input[0] == "pop")
            {
                if (stack.Count == 0)
                    sw.WriteLine(-1);
                else
                    sw.WriteLine(stack.Pop());
            }
            else if (input[0] == "size")
            {
                sw.WriteLine(stack.Count);
            }
            else if (input[0] == "empty")
            {
                if (stack.Count == 0)
                    sw.WriteLine(1);
                else
                    sw.WriteLine(0);
            }
            else if (input[0] == "top")
            {
                if (stack.Count == 0)
                    sw.WriteLine(-1);
                else
                    sw.WriteLine(stack.Peek());
            }
        }

        sw.Close();
        sr.Close();
    }
}

 

 

복습1 풀이 (5/31)

문제 = 스택 구현하고, 입력으로 주어지는 명령을 처리 

 

명령어

  1. push X = 정수 X를 스택에 넣기.
  2. pop = 스택 가장 위 정수 빼고, 그 수 출력 (스택에 들어있는 정수 없으면 -1 출력)
  3. size = 스택에 있는 정수 개수 출력
  4. empty = 스택 비어있으면 1, 아니면 0 출력
  5. top = 스택 가장 위 정수 출력 (스택에 들어있는 정수 없으면 -1 출력)

 

입력

  • 1. N(명령의 수)
  • 2 ~ N개. 명령들 하나씩 주어진다. 

 

범위

  • 1 <= N <= 10,000
  • 1 <= 정수 <= 100,000

 

출력

  • 출력 명령이 주어질 때마다, 한 줄에 하나씩 출력 

 

풀이
스택을 직접 구현해야 함. 
배열로 스택을 직접 구현하자. 
스택은 나중에 들어온 것이 나중에 빠진다. 
이걸 구현하려면 일단 스택 배열의 인덱스를 내가 컨트롤해야 한다. 

 

변수

  • idx = 스택 배열의 인덱스
  • stackArr = 스택 배열 

함수

  • Push(int number) = 스택 배열에 number 넣기.
    • 스택 배열에 number를 넣으면 idx를 늘려 다음 넣을 공간 지정
    • 넣을 때마다 스택 배열 정수 개수를 카운팅 (size++)
  • Pop() = 스택 배열에 가장 끝에 있는 정수 뺴기. 
    • 정수를 빼고(0으로 만들고), 뺀 정수를 출력, idx를 줄인다.
    • 만약 뺄 정수 없으면 -1 출력
  • Size() = 스택 배열에 저장된 정수들 개수 출력
    • size를 출력
  • Empty() = 스택이 비어있는지 아닌지를 출력하는 메서드
    • 비어있으면 1을, 차있으면 0을 출력
  • Top() = 스택 배열 끝에 있는 정수 출력 메서드
    • 끝에 있는 정수 출력
    • 스택 배열 비어있으면 -1출력 

입력과 출력은 for문으로 처리한다. 

 

 

코드1 - 정답

using System.Text;

public class BOJ10828
{
    static StreamReader sr = new StreamReader(Console.OpenStandardInput());
    static StreamWriter sw = new StreamWriter(Console.OpenStandardOutput());
    static StringBuilder sb = new StringBuilder();

    static int idx = 0; 
    static int[] stackArr = new int[20000]; // 넉넉하게 생성 
    static int stackArrSize = 0; 

    static void Main(string[] args)
    {
        int N = int.Parse(sr.ReadLine());
        string[] input;
        string command = "";
        for(int i = 0; i < N; i++)
        {
            input = sr.ReadLine().Split(" ");

            command = input[0];

            switch (command)
            {
                case "push":
                    Push(int.Parse(input[1]));
                    break;
                case "pop":
                    Pop();
                    break;
                case "size":
                    Size();
                    break;
                case "empty":
                    Empty();
                    break;
                case "top":
                    Top();
                    break;
            }
        }

        sw.WriteLine(sb.ToString());

        sr.Close();
        sw.Close();
        sb.Clear();
    }

    public static void Push(int number)
    {
        stackArr[idx++] = number;
        stackArrSize++;
    }

    public static void Pop()
    {
        if(ReturnSize() <= 0)
            sb.AppendLine($"{-1}");
        else
        {
            sb.AppendLine($"{stackArr[idx - 1]}");
            stackArr[idx - 1] = 0; 
            idx--;
            stackArrSize--;
        }
    }

    public static int ReturnSize()
    {
        return stackArrSize;
    }
    public static void Size()
    {
        sb.AppendLine($"{stackArrSize}");
    }

    public static void Empty()
    {
        if(ReturnSize() > 0)
            sb.AppendLine($"{0}");
        else
            sb.AppendLine($"{1}");
    }

    public static void Top()
    {
        if(ReturnSize() > 0)
            sb.AppendLine($"{stackArr[ReturnSize() - 1]}");
        else
            sb.AppendLine($"{-1}");
    }    
}

 

 

코드2 - 정답

using System.Text;

public class BOJ10828
{
    static StreamReader sr = new StreamReader(Console.OpenStandardInput());
    static StreamWriter sw = new StreamWriter(Console.OpenStandardOutput());
    static StringBuilder sb = new StringBuilder();

    static int idx = 0; 
    static int[] stackArr = new int[20000]; // 넉넉하게 생성 

    static void Main(string[] args)
    {
        int N = int.Parse(sr.ReadLine());
        string[] input;
        string command = "";
        for(int i = 0; i < N; i++)
        {
            input = sr.ReadLine().Split(" ");

            command = input[0];

            switch (command)
            {
                case "push":
                    Push(int.Parse(input[1]));
                    break;
                case "pop":
                    Pop();
                    break;
                case "size":
                    Size();
                    break;
                case "empty":
                    Empty();
                    break;
                case "top":
                    Top();
                    break;
            }
        }

        sw.WriteLine(sb.ToString());

        sr.Close();
        sw.Close();
        sb.Clear();
    }

    public static void Push(int number)
    {
        stackArr[idx++] = number;
    }

    public static void Pop()
    {
        if(ReturnSize() <= 0)
            sb.AppendLine($"{-1}");
        else
        {
            sb.AppendLine($"{stackArr[idx - 1]}");
            stackArr[idx - 1] = 0; 
            idx--;
        }
    }

    public static int ReturnSize()
    {
        return idx;
    }
    public static void Size()
    {
        sb.AppendLine($"{idx}");
    }

    public static void Empty()
    {
        if(ReturnSize() > 0)
            sb.AppendLine($"{0}");
        else
            sb.AppendLine($"{1}");
    }

    public static void Top()
    {
        if(ReturnSize() > 0)
            sb.AppendLine($"{stackArr[ReturnSize() - 1]}");
        else
            sb.AppendLine($"{-1}");
    }    
}

idx와 stackArrSize 변수가 같은 역할로 사용되고 있다. 

idx만 사용하도록 수정해줬다.