/ BOJ

BOJ_5430_AC_JAVA

문제 : AC

링크 : BOJ_5430_AC

접근 방식

AC 의 함수

R과 D를 구현해서 수행할 수 있으면 되는 문제이다. 하지만 문제풀이보다도 입력과 출력에 손이 너무 많이가는 문제이다.

예제 입력란에 보면, 배열에 들어있는 정수가 [1,2,3,4]의 형식으로 들어온다. 나는 처음에 이부분을 split을 통해 읽어들였다. 정규표현식에 대해서 정확히 모르기 때문에, 먼저 [ 꺼내고, ‘ , ‘으로 구분지은 뒤 ]를 꺼내는 방식으로 일일이 나누었었다. 후에 찾아보니 StringTokenizer을 통해 값을 읽어오면 “[],”이라는 구분자 하나로 간단하게 구분이 가능했다. split을 통해서도, 정규표현식을 이용하면 한 번에 꺼낼 수 있다고 한다.

출력에서도 까탈스러운 문제였다. Arrays.toString메서드를 통해 출력하는 것과 비슷해보이지만, 해당 출력에는 숫자 사이사이에 공백이 하나 더 들어가서 해당 메서드를 사용하면 틀리게 된다. 결국 StringBuilder를 이용해서 하나하나 구분해서 append해주었다.

문제 해결의 핵심은 덱에서 뒤집는 것의 의미를 이해하는 것이다.

1,2,3,4 가 Deque에 추가 되어있다고 생각해보자. 덱은 앞으로도 꺼내는 게 가능하고, 뒤로도 꺼내는 것이 가능하다. 따라서 R, 뒤집는다는 것의 의미는 그냥 거꾸로 꺼내면 그것이 배열을 뒤집는 게 되는 것이다.

1,2,3,4를 앞에서부터 꺼내면 1, 2, 3 ,4 순으로 꺼내지고, 1,2,3,4를 뒤에서부터 꺼내면 4, 3, 2 ,1 순으로 값이 꺼내진다.

따라서 R명령어를 통해서는 덱을 앞으로 꺼낼지, 뒤로 꺼낼지만 결정하면 되는 것이다.

D 명령어에 대해서는, 덱이 비어있는데 poll 하려고 하면 오류가 나므로, 이 경우에만 error을 출력하게 하면 된다.

풀이 방법

  1. 테스트 케이스 만큼 반복한다.

  2. 명령어는 toCharArray 메서드로 char배열로, 배열의 길이는 int형 으로 읽어들인다.

  3. StringTokenizer로 문자열을 읽어온다. 구분자는 “[],”으로 한다. ( [ 또는 ] 또는 , 으로 나눈다. )

  4. deq에 순서대로 offer시켜준다.

  5. 덱의 reverse 정보를 체크할 boolean형 변수를 하나 선언한다.

  6. 명령어 배열을 하나씩 탐색하며 R일 경우, reverse 변수를 바꿔주고, D일경우에는 reverse 변수에 따라서 앞, 뒤에서 각각 poll 시킨다.

  7. D 명령어가 들어왔을 경우, 덱이 비어있다면 error을 출력하고 바로 다음 테스트 케이스로 continue해준다.

  8. 모든 명령어 수행을 마친 뒤에 덱의 reverse 정보에 따라서 각각 정순, 역순으로 StringBuilder에 append해준다.

  9. 모든 테스트 케이스 반복을 마친 후 저장한 StringBuilder를 출력한다.

소스 코드


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

public class BOJ_5430_AC {

	public static void main(String[] args) throws NumberFormatException, IOException {
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		int T = Integer.parseInt(in.readLine());
		StringBuilder sb = new StringBuilder();
		go:for(int tc=1;tc<=T;tc++) {

			char[] command = in.readLine().toCharArray();

			int  N = Integer.parseInt(in.readLine());
			// split으로 하면 매우매우매우 번거롭다. 그냥 StringTokenizer 쓰자
			StringTokenizer st = new StringTokenizer(in.readLine(),"[],");

			Deque<Integer> deq = new LinkedList<>();

			for(int i=0;i<N;i++) {
				deq.offer(Integer.parseInt(st.nextToken()));
			}
			boolean reverse = false;
			for(int i=0;i<command.length;i++) {

				switch(command[i]) {
				case 'R':
					if(reverse == false) {
						reverse = true;
					}else {
						reverse = false;
					}
					break;
				case 'D':
					if(deq.size() == 0) {
						sb.append("error").append("\n");
						continue go;
					}else if(reverse == true){
						deq.pollLast();
					}else if(reverse == false) {
						deq.pollFirst();
					}
					break;
				}
			}
			sb.append("[");
			for(int i=0,n=deq.size();i<n;i++) {
				if(reverse == true) {
					if(i == n-1) {
						sb.append(deq.pollLast());
					}else {
						sb.append(deq.pollLast()).append(',');
					}
				}else {
					if(i == n-1) {
						sb.append(deq.pollFirst());
					}else {
						sb.append(deq.pollFirst()).append(',');
					}
				}
			}
			sb.append("]").append('\n');
		}
		System.out.print(sb);
	}

}