Blog

백준 5430번: AC, 덱의 방향을 바꿔 명령 처리하기

뒤집는 대신 읽는 방향을 바꿉니다

백준 5430번 AC는 R로 배열의 방향을 뒤집고 D로 맨 앞의 수를 버리는 명령을 처리하는 문제입니다. 빈 배열에서 D를 실행하면 error를 출력합니다.

당시에는 양쪽 끝에서 값을 뺄 수 있는 덱을 사용했습니다. way가 현재 방향을 나타냅니다. R을 만나면 배열을 직접 뒤집지 않고 이 값만 바꿉니다. D를 만났을 때 정방향이면 앞에서, 역방향이면 뒤에서 값을 뺍니다.

입력 배열은 대괄호와 쉼표가 들어 있는 문자열입니다. StringTokenizer로 숫자를 나눈 뒤 덱에 넣었습니다.

제출 코드

Java
import java.io.*;
import java.util.*;
class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

        // 케이스 개수 T 입력
        int T = Integer.parseInt(br.readLine());
        for (int t = 0; t < T; t++) {

            // 함수 배열 cmd 입력
            String cmdLine = br.readLine();
            int cLen = cmdLine.length();
            char[] cmd = new char[cLen];
            for (int i = 0; i < cLen; i++) {
                cmd[i] = cmdLine.charAt(i);
            }
            // 배열에 들어있는 수 n 입력
            int n = Integer.parseInt(br.readLine());

            // 배열을 입력 받을 Deque 타입 선언
            Deque<Integer> dq = new ArrayDeque<>();

            // StringTokenizer로 문자열 분리 "[", "]", "," 3개로 분리한다.
            StringTokenizer st = new StringTokenizer(br.readLine(), "[],");

            // 정수형태로 Deque에 입력
            for (int i = 0; i < n; i++) {
                dq.add(Integer.parseInt(st.nextToken()));
            }

            // 뒤집기 상태를 관리할 way, true = 앞->뒤
            boolean way = true;

            // 에러 상태를 관리할 error, dq가 비어있는데 D를 한번이라도 한 순간 true로 변경
            boolean error = false;
            for (int i = 0; i < cLen; i++) {
                if (cmd[i] == 'R') {
                    way = !way;
                } else if (cmd[i] == 'D') {
                    if (!dq.isEmpty()) {
                        if (way) {
                            Integer polled = dq.pollFirst();
                        } else {
                            Integer polled = dq.pollLast();
                        }
                    } else {
                        error = true;
                    }
                }
            }

            // 출력 구현
            if (!error) {
                // dq에 상태에 따라 뒤집어야하므로, dq를 List로 변환
                ArrayList<Integer> arr = new ArrayList<>(dq);

                // way의 값에 따라 출력
                if (way) {
                    bw.write(arr.toString().replace(" ", ""));
                } else {
                    Collections.reverse(arr);
                    bw.write(arr.toString().replace(" ", ""));
                }
            } else {
                bw.write("error");
            }
            bw.write("\n");
            bw.flush();
        }
    }
}

문자열 구분자와 덱에서 배운 점

Java
// StringTokenizer로 문자열 분리 "[", "]", "," 3개로 분리한다.
StringTokenizer st = new StringTokenizer(br.readLine(), "[],");

구분자 인수의 "[],"는 이 문자열 전체를 하나의 구분자로 찾지 않고 [, ], ,를 각각 구분자로 사용합니다. 그래서 숫자 토큰을 순서대로 읽을 수 있습니다.

덱에서 앞의 값을 꺼낼 때는 pollFirst()를 쓰고 뒤의 값은 pollLast()로 꺼냅니다. 코드에서는 삭제 전에 비어 있는지부터 확인해서 비어 있으면 error 상태를 남깁니다. 한 번 발생한 오류는 뒤에 다른 명령이 와도 지우지 않습니다.

출력할 때는 덱을 리스트로 바꾸고 역방향이면 그때 한 번 뒤집습니다. 리스트의 문자열 표현에서 공백을 없애 문제에서 요구하는 대괄호와 쉼표 형식으로 출력합니다.