[백준] 28278 스택 2 자바

이다혜·2023년 11월 16일
0

백준

목록 보기
1/29
post-thumbnail

📎 문제 출처


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

📌 문제 설명


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

명령은 총 다섯 가지이다.

1 X: 정수 X를 스택에 넣는다. (1 ≤ X ≤ 100,000)
2: 스택에 정수가 있다면 맨 위의 정수를 빼고 출력한다. 없다면 -1을 대신 출력한다.
3: 스택에 들어있는 정수의 개수를 출력한다.
4: 스택이 비어있으면 1, 아니면 0을 출력한다.
5: 스택에 정수가 있다면 맨 위의 정수를 출력한다. 없다면 -1을 대신 출력한다.

📌 Code1


처음에는 Scanner와 System.out.println()을 사용해서 풀었는데 runtime 에러가 발생했다.
찾아보니 Scanner보다 BufferedReader가 훨씬 빠르다고 한다.
또, 매번 System.out.println으로 출력하는 것보다 StringBuilder에 쌓아뒀다가 한번에 출력하는 것이 좋다고 해서 수정했더니 겨우겨우 성공했다.

성공은 했지만 메모리랑 시간이 형편없어 보인다..

package com.ll;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Stack;
import java.util.StringTokenizer;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringBuilder sb = new StringBuilder();
        StringTokenizer st;
        Stack<Integer> stack = new Stack<>();
        int N = Integer.parseInt(br.readLine());

        for(int i = 0; i < N; i++) {
            String str = br.readLine();
            st = new StringTokenizer(str);

            switch(st.nextToken()) {
                case "1" :
                    stack.push(Integer.parseInt(st.nextToken()));
                    break;
                case "2" :
                    if(stack.isEmpty())
                        sb.append(-1).append('\n');
                    else
                        sb.append(stack.pop()).append('\n');
                    break;
                case "3" :
                    sb.append(stack.size()).append('\n');
                    break;
                case "4" :
                    if(stack.isEmpty())
                        sb.append(1).append('\n');
                    else
                        sb.append(0).append('\n');
                    break;
                case "5" :
                    if(stack.isEmpty())
                        sb.append(-1).append('\n');
                    else
                        sb.append(stack.peek()).append('\n');
                    break;
            }
        }

        System.out.print(sb.toString());
    }

}

📌 Code2


두 번째는 Scanner와 StringBuilder를 사용하고 코드도 좀 줄여봤다.
성공은 했지만 메모리랑 시간이 더 형편없어졌다..

package com.ll;

import java.util.Scanner;
import java.util.Stack;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        StringBuilder sb = new StringBuilder();
        Stack<Integer> stack = new Stack<>();

        int N = scanner.nextInt();
        for(int i = 0; i < N; i++) {
            int n = scanner.nextInt();
            switch (n) {
                case 1:
                    stack.push(scanner.nextInt()); 
                    break;
                case 2:
                    sb.append((stack.isEmpty()?-1:stack.pop())+"\n"); 
                    break;
                case 3:
                    sb.append(stack.size()+"\n"); 
                    break;
                case 4:
                    sb.append((stack.isEmpty()?1:0)+"\n"); 
                    break;
                case 5:
                    sb.append((stack.isEmpty()?-1:stack.peek())+"\n");
            }
        }
        System.out.println(sb.toString());
    }

}

📌 Code3


마지막으로 배열로 스택을 구현해서 풀어봤다.
스택의 맨 위인 top만 생각하면 돼서 간단했다.

시간도 조금 더 단축됐다.

package com.ll;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {
    static BufferedReader br;
    static StringBuilder sb;
    static int[] stack = new int[1000000];
    static int top = 0;

    public static void main(String[] args) throws IOException {
        br = new BufferedReader(new InputStreamReader(System.in));
        sb = new StringBuilder();
        StringTokenizer st;

        int N = Integer.parseInt(br.readLine());

        for(int i = 0; i < N; i++) {
            st = new StringTokenizer(br.readLine());
            switch(st.nextToken()) {
                case "1" : push(Integer.parseInt(st.nextToken())); break;
                case "2" : pop(); break;
                case "3" : size(); break;
                case "4" : empty(); break;
                case "5" : peek(); break;
            }
        }
        System.out.print(sb.toString());
    }

    static void push(int n) {
        stack[top++] = n;
    }
    static void pop() {
        if(top > 0) sb.append(stack[--top]).append("\n");
        else sb.append(-1).append("\n");
    }
    static void size() {
        sb.append(top).append("\n");
    }
    static void empty(){
        if(top == 0) sb.append(1).append("\n");
        else sb.append(0).append("\n");
    }
    static void peek() {
        if(top == 0) sb.append(-1).append("\n");
        else sb.append(stack[top-1]).append("\n");
    }

}

📌 일단 확실히 Scanner보다는 BufferedReader, String보다는 StringBuilder가 성능이 좋다는 것을 눈으로 확인했으니 앞으로 코드에는 저 두 개를 써봐야겠다.

0개의 댓글