백준 5430번: AC, 덱의 방향을 바꿔 명령 처리하기
뒤집는 대신 읽는 방향을 바꿉니다
백준 5430번 AC는 R로 배열의 방향을 뒤집고 D로 맨 앞의 수를 버리는 명령을 처리하는 문제입니다. 빈 배열에서 D를 실행하면 error를 출력합니다.
당시에는 양쪽 끝에서 값을 뺄 수 있는 덱을 사용했습니다. way가 현재 방향을 나타냅니다. R을 만나면 배열을 직접 뒤집지 않고 이 값만 바꿉니다. D를 만났을 때 정방향이면 앞에서, 역방향이면 뒤에서 값을 뺍니다.
입력 배열은 대괄호와 쉼표가 들어 있는 문자열입니다. StringTokenizer로 숫자를 나눈 뒤 덱에 넣었습니다.
제출 코드
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();
}
}
}문자열 구분자와 덱에서 배운 점
// StringTokenizer로 문자열 분리 "[", "]", "," 3개로 분리한다.
StringTokenizer st = new StringTokenizer(br.readLine(), "[],");구분자 인수의 "[],"는 이 문자열 전체를 하나의 구분자로 찾지 않고 [, ], ,를 각각 구분자로 사용합니다. 그래서 숫자 토큰을 순서대로 읽을 수 있습니다.
덱에서 앞의 값을 꺼낼 때는 pollFirst()를 쓰고 뒤의 값은 pollLast()로 꺼냅니다. 코드에서는 삭제 전에 비어 있는지부터 확인해서 비어 있으면 error 상태를 남깁니다. 한 번 발생한 오류는 뒤에 다른 명령이 와도 지우지 않습니다.
출력할 때는 덱을 리스트로 바꾸고 역방향이면 그때 한 번 뒤집습니다. 리스트의 문자열 표현에서 공백을 없애 문제에서 요구하는 대괄호와 쉼표 형식으로 출력합니다.