import java.util.*;
import java.io.*;
public class Main {
static String[] arr;
static Queue<Character> q = new LinkedList<>();
static Queue<Character> answer = new LinkedList<>();
static int start, end;
static int isReverse;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int T = Integer.parseInt(br.readLine());
StringBuilder sb = null;
for(int i=0; i<T; i++) {
sb = new StringBuilder();
isReverse = -1;
start = 0;
q.clear();
String p = br.readLine();
for(int j=0; j<p.length(); j++) {
q.add(p.charAt(j));
}
int n = Integer.parseInt(br.readLine());
end = n-1;
arr = new String[n];
String temp = br.readLine();
arr = temp.substring(1, temp.length()-1).replace(",", " ").split(" ");
readFunction();
if(isNone()) {
sb.append("error");
} else {
sb.append("[");
if(isReverse == 1) {
for(int k = start ; k>=end; k--) {
sb.append(arr[k] + ",");
}
} else {
for(int k = start ; k<=end; k++) {
sb.append(arr[k] + ",");
}
}
sb.deleteCharAt(sb.length()-1);
sb.append("]");
}
System.out.println(sb);
}
}
public static void readFunction() {
while(!q.isEmpty()) {
char cmd = q.poll();
switch(cmd) {
case 'R' :
reverseIdx();
break;
case 'D' :
deleteIdx();
break;
}
}
}
public static void reverseIdx() {
int temp = start;
start = end;
end = temp;
isReverse *= (-1);
}
public static void deleteIdx() {
if(isReverse == 1) {
start--;
} else if(isReverse == -1) {
start++;
}
}
public static boolean isNone() {
boolean answer= false;
if(isReverse == 1) {
if(start < end) {
answer= true;
}
}
if(isReverse == -1) {
if(start > end) answer = true;
}
return answer;
}
}
테스트 케이스는 맞았는데, 틀렸습니다를 받았다.
1
D
1
4
를 넣으니, ]
만 출력됐다.
즉 isNone()
이 true로 동작해서 error를 출력했다는말이다.
근데 문제를 다시 살펴보니,, 조건을 헷갈렸다.
값이 비었을 때 (isNone == ture) error를 출력하는게 아니라, 값이 비었는데 D를 수행하면 그때 출력하라는 것이다.
따라서 D를 수행할 때, 값이 비어있으면 에러 출력으로 연결될 수 있게 플래그 변수를 하나 사용했다.
readFunction() 에서 case 'D'에 아래 코드를 추가했다.
if(isNone()) isError = true;
+수정한 후 주어진 테스트 케이스로 돌려보니 세번째의 값이 error로 출력됐다.
테스트케이스식으로 작동하는 코드에서 어떤 변수를 사용한다면, 꼭 각 테케가 돌아갈 때 마다 해당 변수를 초기화시켜주는것을 잊지말자!! (isError=false 초기화)
import java.util.*;
import java.io.*;
public class Main {
static String[] arr;
static Queue<Character> q = new LinkedList<>();
static Queue<Character> answer = new LinkedList<>();
static int start, end;
static int isReverse;
static boolean isError = false;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int T = Integer.parseInt(br.readLine());
StringBuilder sb = null;
for(int i=0; i<T; i++) {
sb = new StringBuilder();
isReverse = -1;
start = 0;
isError = false;
q.clear();
String p = br.readLine();
for(int j=0; j<p.length(); j++) {
q.add(p.charAt(j));
}
int n = Integer.parseInt(br.readLine());
end = n-1;
arr = new String[n];
String temp = br.readLine();
arr = temp.substring(1, temp.length()-1).replace(",", " ").split(" ");
readFunction();
if(isError) {
sb.append("error");
} else {
sb.append("[");
if(isReverse == 1) {
for(int k = start ; k>=end; k--) {
sb.append(arr[k] + ",");
}
} else {
for(int k = start ; k<=end; k++) {
sb.append(arr[k] + ",");
}
}
if(sb.length()>1)sb.deleteCharAt(sb.length()-1);
sb.append("]");
}
System.out.println(sb);
}
}
public static void readFunction() {
while(!q.isEmpty()) {
char cmd = q.poll();
switch(cmd) {
case 'R' :
reverseIdx();
break;
case 'D' :
if(isNone()) isError = true;
deleteIdx();
break;
}
}
}
public static void reverseIdx() {
int temp = start;
start = end;
end = temp;
isReverse *= (-1);
}
public static void deleteIdx() {
if(isReverse == 1) {
start--;
} else if(isReverse == -1) {
start++;
}
}
public static boolean isNone() {
boolean answer= false;
if(isReverse == 1) {
if(start < end) {
answer= true;
}
}
if(isReverse == -1) {
if(start > end) answer = true;
}
return answer;
}
}
보통 풀이를 찾아보니, 배열을 사용하려다가 시간초과를 접했다고한다.
(그런 사람들 풀이를 보니 배열을 뒤집을 때 진짜 뒤집은 배열을 다른 배열에다가 저장하고있음..)
근데, 난 데이터가 너무많아서 그건 너무 비효율적이라고 생각했기때문에, 뒤집는거나 삭제하는거나 인덱스를 사용해서 풀었다.
따라서 배열을 사용하더라도 시간초과가 나지는 않았다.
근데, 더 찾아보니 시간초과때문에 배열이 아닌 Deque를 사용하더라.
Queue는 사용해도 Deque 자료구조를 많이 사용하지 않았었던 나기에 이 풀이를 공부한다.
import java.io.*;
import java.util.*;
public class Main {
static ArrayDeque<Integer> deque;
static StringBuilder sb = new StringBuilder();
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int T = Integer.parseInt(br.readLine());
while(T --> 0) {
String p = br.readLine();
int number = Integer.parseInt(br.readLine());
StringTokenizer st = new StringTokenizer(br.readLine(),"[],");
deque = new ArrayDeque<Integer>();
for(int i=0; i<number; i++) {
deque.add(Integer.parseInt(st.nextToken()));
}
AC(p);
}
System.out.println(sb);
} // End of main
static void AC(String p) {
boolean forward_direction = true;
for(char function : p.toCharArray()) {
if(function == 'R') {
forward_direction = !forward_direction;
continue;
}
// 정방향일 때
if( forward_direction ) {
// 덱이 비었으면,
if(deque.pollFirst() == null) {
sb.append("error\n");
return;
}
}
// 역방향 일때 forward_direction = true
else {
if(deque.pollLast() == null) {
sb.append("error\n");
return;
}
}
}
makePrintString(forward_direction);
}
private static void makePrintString(boolean forward_direction) {
sb.append('[');
if(deque.size() > 0) {
if(forward_direction) {
sb.append(deque.pollFirst());
while(!deque.isEmpty()) {
sb.append(',').append(deque.pollFirst());
}
}
else {
sb.append(deque.pollLast());
while(!deque.isEmpty()) {
sb.append(',').append(deque.pollLast());
}
}
}
sb.append(']').append('\n');
} // End of makePrintString
} // End of class
StringTokenizer st = new StringTokenizer(br.readLine(),"[],");
deque = new ArrayDeque<Integer>();
for(int i=0; i<number; i++) {
deque.add(Integer.parseInt(st.nextToken()));
}
if(function == 'R') {
forward_direction = !forward_direction;
continue;
}
-> boolean 타입의 변수를 특정 상황에 계속 체인지시켜주려면 !
연산자를 사용하면된다
역방향도 deque.pollLast()만 다르고 과정은 같습니다.
if(forward_direction) {
sb.append(deque.pollFirst());
while(!deque.isEmpty()) {
sb.append(',').append(deque.pollFirst());
}
}
else {
sb.append(deque.pollLast());
while(!deque.isEmpty()) {
sb.append(',').append(deque.pollLast());
}
}
public StringTokenizer(String str,String delim);
: 특정 delim으로 문자열을 분리합니다.참고
https://velog.io/@lifeisbeautiful/Java-%EB%B0%B1%EC%A4%80-5430%EB%B2%88-AC-%EC%9E%90%EB%B0%94