백준 10866 덱 [JAVA]

Ga0·2023년 7월 4일
0

baekjoon

목록 보기
78/125

문제 해석

  • 첫번째 줄로 명령어의 수(N)을 입력받는다.
  • 명령어의 수(N)을 입력받았다면 두번째 줄부터 한 줄에 한개의 명령어씩 입력받는다.
  • 명령의 종류는 아래와 같다.
    push_front X: 정수 X를 덱의 앞에 넣는다.
    push_back X: 정수 X를 덱의 뒤에 넣는다.
    pop_front: 덱의 가장 앞에 있는 수를 빼고, 그 수를 출력한다. 만약, 덱에 들어있는 정수가 없는 경우에는 -1을 출력한다.
    pop_back: 덱의 가장 뒤에 있는 수를 빼고, 그 수를 출력한다. 만약, 덱에 들어있는 정수가 없는 경우에는 -1을 출력한다.
    size: 덱에 들어있는 정수의 개수를 출력한다.
    empty: 덱이 비어있으면 1을, 아니면 0을 출력한다.
    front: 덱의 가장 앞에 있는 정수를 출력한다. 만약 덱에 들어있는 정수가 없는 경우에는 -1을 출력한다.
    back: 덱의 가장 뒤에 있는 정수를 출력한다. 만약 덱에 들어있는 정수가 없는 경우에는 -1을 출력한다.

코드

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

public class Main {

    static LinkedList<Integer> queue = new LinkedList<>(); //큐(덱)

    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()); //명령어의 수(N)

        while(N --> 0){ //명령어의 수만큼 명령어를 입력받는다.(한줄에 하나씩)
            String str = br.readLine(); //명령어(한줄에 하나)

            if(str.contains("push")){ //명령어에 push가 들어가는 경우는 StringTokenizer로 쪼개야 함
                StringTokenizer st = new StringTokenizer(str);

                if(st.nextToken().contains("front")){//push -> front 명령어
                    push_front(Integer.parseInt(st.nextToken()));
                }else if(str.contains("back")){ //push -> back 명령어
                    push_back(Integer.parseInt(st.nextToken()));
                }
            }else if(str.contains("pop")){ //pop 관련 명령어
                if(str.contains("front")){//pop -> front 명령어
                    sb.append(pop_front()).append("\n");
                }else if(str.contains("back")){ //pop -> back 명령어
                    sb.append(pop_back()).append("\n");
                }
            }else if(str.contains("size")){ //size 명령어
                sb.append(size()).append("\n");
            }else if(str.contains("empty")){ //empty 명령어
                sb.append(empty()).append("\n");
            }else if(str.contains("front")){ //front 명령어
                sb.append(front()).append("\n");
            }else if(str.contains("back")){ //back 명령어
                sb.append(back()).append("\n");
            }
        }
        br.close();
        System.out.println(sb);
    }

    //push_front 명령어
    static void push_front(int X){
        queue.addFirst(X); //맨 앞에 해당 숫자 추가
    }
    //push_back 명령어
    static void push_back(int X){
        queue.addLast(X); //맨 뒤에 해당 숫자 추가
    }
    //pop_front 명령어
    static int pop_front(){
        if(empty() == 1){
            return -1;
        }
        return queue.removeFirst(); //가장 앞 인덱스 요소 뽑기
    }
    //pop_back 명령어
    static int pop_back(){
        if(empty() == 1){
            return -1;
        }
        return queue.removeLast(); //마지막 인덱스 요소 뽑기
    }
    //size 명령어
    static int size(){
        return queue.size();
    }
    //empty 명령어
    static int empty(){
        return (queue.size() <= 0) ? 1 : 0;
    }
    //front 명령어
    static int front(){
        if(empty() == 1){//비어있는 경우 -1 출력
            return -1;
        }
        return queue.peekFirst();
    }
    //back 명령어
    static int back(){
        if(empty() == 1){ //비어있는 경우 -1 출력
            return -1;
        }
        return queue.peekLast();
    }
}

참고한 코드

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

public class Main {

    static int front = 0;//덱 첫번째 요소
    static int back = 0; //덱 마지막 요소
    static int size = 0; //덱 사이즈
    static int[] queue = new int[10000]; //덱(명령의 수 N (1 ≤ N ≤ 10,000)이기 때문에 크기를 10000으로 지정)

    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()); //명령어의 수

        for(int i = 0; i < N; i++){
            // push_back과 push_front일 경우는 넣을 정수를 공백으로 구분해서 넣기 때문에
            // 공백으로 구분하여 문자열 배열에 넣는다.
            String[] order  = br.readLine().split(" ");

            // if문을 통해서 order[0] == push_back 이런식으로 해도 되지만
            // 그럴 경우 명령어 한번에 해당 명령어 배열을 명령어의 종류만큼 호출해야하기 때문에 좋지 않다.
            switch (order[0]){
                case "push_front" : {
                    push_front(Integer.parseInt(order[1]));
                    break;
                }

                case "push_back" : {
                    push_back(Integer.parseInt(order[1]));
                    break;
                }

                case "pop_front" : {
                    sb.append(pop_front()).append('\n');
                    break;
                }

                case "pop_back" : {
                    sb.append(pop_back()).append('\n');
                    break;
                }

                case "size" : {
                    sb.append(size()).append('\n');
                    break;
                }

                case "empty" : {
                    sb.append(empty()).append('\n');
                    break;
                }

                case "front" : {
                    sb.append(front()).append('\n');
                    break;
                }

                case "back" : {
                    sb.append(back()).append('\n');
                    break;
                }
            }
        }
        br.close();
        System.out.println(sb);
    }

    static void push_front(int element){
        // 원소를 먼저 넣은 뒤 front을 감소시킨다.
        queue[front] = element;
        // 음수가 되지 않도록 배열 크기만큼 더해준다.
        front = (front - 1 + 10000) % 10000;
        size++;
    }

    static void push_back(int element){
        // deque[9999] 까지 꽉 찼을 경우 0으로 가리키기 위해 배열 크기만큼 나눠 나머지를 구한다.
        back = (back + 1) % 10000;
        size++;
        queue[back] = element;
    }

    static int pop_front(){
        if (size == 0) {
            return -1;
        }
        // front + 1이 front원소이므로 해당 원소를 임시 변수에 넣고 나서 front를 +1해준다.
        int ret = front();
        front = (front + 1) % 10000;
        size--;
        return ret;
    }

    static int pop_back(){
        if (size == 0) {
            return -1;
        }
        int result = back();
        back = (back - 1 + 10000) % 10000;
        size--;
        return result;
    }

    //덱의 사이즈 반환하는 메소드
    static int size(){
        return size;
    }

    //덱이 비어있는지 판별하는 메소드
    static int empty(){
        if(size == 0){
            return 1;
        }
        return 0;
    }

    /*
        원소가 한 개만 있을 경우 해당 원소는 front 이자 back 원소가 된다.
        방지하기 위해 queue[(front+1) % 10000]을 한다.
    */
    // 가장 앞에있는 요소 가져오는 메소드
    static int front(){
        if(size == 0){ //비어있으면 -1출력
            return -1;
        }
        return queue[(front+1) % 10000]; //가장 앞 요소는 맨 앞의
    }

    //가장 마지막 요소 출력
    static int back(){
        if(size == 0){
            return -1;
        }
        return queue[back];
    }
}
        

결과

1

2

느낀 점

  • 기본 배열 코드는 이해하는 데만 시간이 꽤 걸렸다.

0개의 댓글