시간 제한이 꽤 빡빡하기 때문에 배열을 진짜 역순 정렬하고, index를 삭제하기에는 무조건 시간 초과가 날 것 같았다
물론 좋은 자료구조형을 쓰게 되면 어느정도 줄일 수는 있었겠지만 ?
나는 그래서 원래 배열은 가만히 두고, 배열의 상태를 저장할 수 있는 3가지의 변수를 이용하였다
이거만 보면 별로 안 어려워 보이지 ? 근데 5번 틀림
일단 배열의 범위를 내가 조작하기 때문에 error 조건에 대한 핸들링을 신경써야 한다.
그리고, 극악의 String parsing을 보여준다 ("[1,2,3,4]" 이렇게 입력을 준다 ...)
1. leftIndex와 rightIndex가 같아지는 시점에, 즉 배열의 크기가 0일 때 남은 명령어가 없거나 R만 남아있어야 한다.
2. String을 int타입으로 바꾸는 과정에서 각종 Exception을 주의해야 한다.
난 백준 다 좋은데 경계값 예외처리로 장난 좀 안 쳤으면 좋겠다 ㅎㅎ
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
/**
* <pre>
* 백준 5430. AC
* 시간초과에 유의하기 위해 reverse, delete를 배열에 직접 구현하는 것이 아닌, 범위를 설정하고 방향을 설정하는 변수로 저장
* 명령어에 따라 해당 변수들을 조작하며 최종 정답을 구하였음.
* </pre>
* @author 세진
*
*/
public class Main {
public static void main(String[] args) throws NumberFormatException, IOException {
// user input을 위한 BufferedReader 객체 생성
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
// 테스트케이스 수 t 입력받아 Integer로 parse
int t = Integer.parseInt(br.readLine());
// 입력받은 t만큼 반복
// 현재 test case에서 예외 발생 시 바로 다음 case로 넘어갈 수 있게 조치하기 위한 nextCase 레이블 부여
nextCase:
for (int test_case = 1; test_case <= t; test_case++) {
// 배열조작 명령어 commands 배열에, input 배열 길이 n에 입력받음
char[] commands = br.readLine().toCharArray();
int n = Integer.parseInt(br.readLine());
// case 1) input배열 크기가 0일 때 (이 경우에는 더 이상 요소를 지울 수 없음)
if (n == 0) {
// 0이기 때문에 무조건 입력 "[]" 으로 주어지기 때문에 readLine으로 저장할 필요 없는 입력 날리기
br.readLine();
// commands 배열을 돌면서 반복
for (int i = 0; i < commands.length; i++) {
// D (삭제) 명령어가 나오면 error 출력하고 다음 case로 넘어감
if (commands[i] == 'D') {
System.out.println("error");
continue nextCase;
}
}
// D 명령어 없이 R (reverse) 명령어만 나오게 된다면 빈 배열 그대로 출력 후 다음 case로 넘어감
System.out.println("[]");
continue nextCase;
}
// case 2) input 배열 크기가 0이 아닐 때
// 배열 입력받기 위한 arr 배열 선언
int[] arr = new int[n];
// 배열 입력 string을 inputStr에 입력받고, 뒤에 '[', ']' 을 떼어내고 "," 기준으로 split
String inputStr = br.readLine();
String arrStr = new String(Arrays.copyOfRange(inputStr.toCharArray(), 1, inputStr.length() - 1));
String[] arrStrSplit = arrStr.split(",");
// split 결과 값 하나씩 Integer로 parse 후 arr에 저장
for (int i = 0; i < n; i++) {
arr[i] = Integer.parseInt(arrStrSplit[i]);
}
// isReverse : 역순인지 아닌지 저장하는 boolean 변수
// leftStart : 왼쪽 인덱스 시작점을 저장할 정수형 변수 (정방향일때 D명령어가 들어오면 하나씩 늘려 범위를 축소한다)
// rightStart : 오른쪽 인덱스 시작점을 저장할 정수형 변수 (역방향일때 D명령어가 들어오면 하나씩 줄여 범위를 축소한다)
boolean isReverse = false;
int leftStart = 0;
int rightStart = n;
// commands 배열의 크기만큼 반복
for (int i = 0; i < commands.length; i++) {
if (commands[i] == 'R') { // R 명령어이면, isReverse를 현재 값의 반대값으로 바꿈
isReverse = !isReverse;
continue;
}
else if (commands[i] == 'D') { // D 명령어이면, isReverse의 방향에 따라 처리
if (isReverse) { // 역순이면 rightStart를 1 감소
rightStart--;
}
else { // 정방향이면 leftStart를 1 증가
leftStart++;
}
// D명령어로 인해 범위가 줄어들다가 같아지는 시점이 오게 되면
if (leftStart == rightStart) {
// 마지막 명령어이면 빈 배열 출력 후 다음 case로 넘어감
if (i == commands.length - 1) {
System.out.println("[]");
continue nextCase;
}
// 마지막 명령어가 아니면 남은 명령어들 중 D가 있는지 확인하기 위해 반복
for (int j = i; j < commands.length; j++) {
// D 있으면 오류이기 때문에 error 출력 후 다음 case로 넘어감
if (commands[j] == 'D') {
System.out.println("error");
continue nextCase;
}
}
// D가 없고 R만 있으면 빈 배열 출력 후 다음 case로 넘어감
System.out.println("[]");
continue nextCase;
}
}
}
// 확인하기 위한 출력구문
// System.out.printf("left : %d, right : %d, isReverse : %b\n", leftStart, rightStart, isReverse);
// 반복문 종료 후 출력 String을 만들기 위한 StringBuilder 객체 생성
StringBuilder sb = new StringBuilder();
sb.append("[");
// 만약 남아있는 index가 1개라면 하나의 요소만 딱 추가해 괄호 닫아서 출력하고 다음 case로 넘어감
if (leftStart == rightStart - 1) {
sb.append(arr[leftStart]);
sb.append("]");
System.out.println(sb.toString());
continue nextCase;
}
// 만약 정방향이라면 (역방향이 아니라면)
if (!isReverse) {
// left부터 right까지의 index들을 추가
for (int i = leftStart; i < rightStart; i++) {
sb.append(arr[i]);
if (i != rightStart - 1) {
sb.append(",");
}
else {
sb.append("]");
}
}
}
else { // 역방향이면
// right부터 left까지의 index들을 추가
for (int i = rightStart - 1; i >= leftStart; i--) {
sb.append(arr[i]);
if (i != leftStart) {
sb.append(",");
}
else {
sb.append("]");
}
}
}
// 답 출력
System.out.println(sb.toString());
}
}
}
일단 어거지로 풀긴 풀었는데 .. 내 코드를 다른 사람이 이해하기 쉽게 짜는 것 같진 않다
중복되는 코드들도 생각보다 많은 것 같고 해서 ,, 연습이 좀 더 필요할 듯