[백준] 10828-스택-Java

screenshot

[백준] 10828-스택-Java


❓문제

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

명령은 총 다섯 가지이다.

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

❗️스택이란

우선 풀이에 앞서, 스택이란 무엇인지 한번 알아보자.
스택의 사전적 의미로는 ‘쌓다’, ‘더미’라는 뜻을 가지고 있다.
Stack은 Java의 Collection 프레임워크의 일부이다.

  • 스택의 특징
    • LIFO(Last In First OUT) 후입선출의 구조를 가지고있다.

예를들어 프링글스 과자를 떠올려보자.
과자는 맨아래 있는 것이 가장먼저 들어갔으며, 가장 위에 있는 것이 가장 마지막에 들어갔을 것이다.
우리가 과자를 먹을 때는 가장 마지막에 들어간 것을 가장 먼저 꺼내먹으며, 가장 먼저 들어간 것을 가장 마지막에 먹을 것이다.
이와 같은 스택의 특징을 유의하며 풀어보자.

🖊️풀이법

풀이는 아래의 코드 주석을 참조하자.

정답 코드

import java.util.*;
import java.io.*;


public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringBuilder sb = new StringBuilder();
        int N = Integer.parseInt(br.readLine());
        ArrayList<Integer> list = new ArrayList<Integer>();
        for(int i = 0; i< N; i++){

            String s = br.readLine();

            //push X인 경우
            if(s.contains("push")){
                int pushN = Integer.parseInt(s.substring(5)); //5번째 문자열 부터 숫자가 입력되므로 정수로 변환
                list.add(pushN); //리스트에 추가
            }

            //pop인 경우
            if(s.equals("pop")){
                if(list.size() == 0){ //list에 아무것도 없다면
                    sb.append(-1).append('\n'); // -1을 sb에 저장
                } else{
                    sb.append(list.get(list.size()-1)).append('\n'); //그게 아니라면 list의 마지막 요소를 sb에 저장
                    list.remove(list.size()-1); //마지막 요소 삭제
                }
            }
            
            //size인 경우
            if(s.equals("size")){ 
                sb.append(list.size()).append('\n'); //list의 사이즈를 sb에 저장
            }
            
            //empty인 경우
            if(s.equals("empty")){
                if(list.size() == 0){ //list가 비어있는 경우
                    sb.append(1).append('\n'); //sb에 1을 저장
                } else {   //비어있지 않는 경우
                    sb.append(0).append('\n'); //sb에 0을 저장
                }
            }

            if(s.equals("top")){ //top인 경우
                if(list.size() == 0){ //list가 비어있는 경우
                    sb.append(-1).append('\n'); //sb에 -1을 저장
                } else {
                    sb.append(list.get(list.size()-1)).append('\n'); //마지막 list요소를 sb에 저장
                }
            }
        }
        System.out.println(sb);
    }
}

정리

해당 문제는 Stack을 이용하면 더 간편하게 풀 수 있다.
그런데, 문제를 풀며 ArrayList와 Stack이 상당한 비슷한 느낌을 받았다.
그래서 두가지의 차이를 알아보는 와중에 이러한 사실을 발견했다.

  • ArrayList는 기존의 Vector을 개선한 것으로 거의 Vector와 유사하지만, Vector는 쓰레드 동기화를 지원하고 ArrayList는 동기화를 지원하지 않는다.

다시 말해, Stack은 Vector을 상속받았기 때문에 동기화를 지원하지만 ArrayList는 동기화를 지원하지 않는다.
이 말은 Stack이나 Vector는 쓰레드 동기화를 통하여, 좀 더 안정성이 높다고 볼 수 있을 것 같다. :)