1일1알고/Java Algorithm

[23/05/02] B1406

kim chan jin 2023. 5. 4. 11:46
package baekjoon;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Stack;

public class B1406 {
    static Stack<String> stack = new Stack<>();

    public static void main(String[] args) throws IOException {

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); // abcd
        char[] charArr = br.readLine().toCharArray();

        // stack에 담기
        for(int i=0; i<charArr.length; i++) {
            stack.push(String.valueOf(charArr[i]));
        }

        // cursor 담기
        stack.push("C"); // abcdC

        int M = Integer.parseInt(br.readLine()); // 3

        for(int i=0; i<M; i++) {
            String str = br.readLine();
            str = str.replace(" ", "");
            editor(str);
        }

        stack.remove("C");

        for(String x : stack) {
            System.out.print(x);
        }
    }

    public static void editor(String instruction) {
        char[] charArr = instruction.toCharArray();
        ArrayList<String> arrList = new ArrayList<>();
        int indexOfCursor = stack.search("C");

        if(charArr[0] == 'L' && indexOfCursor > 0 && indexOfCursor < stack.size()) { // 커서를 왼쪽으로 한칸 옮김, 만약 커서가 문장 맨 앞이 아니라면
            untilCursorAndPop(arrList);
            arrList.add(stack.pop()); // cursor 앞 문자 pop하고 그 요소를 arrList에 저장
            stack.push("C"); // cursor 푸쉬
            repairStack(arrList);

        } else if(charArr[0] == 'D' && indexOfCursor > 0 && indexOfCursor < stack.size()) { // 커서를 오른쪽으로 한칸 옮기, 만약 커서가 문장 맨 뒤라면 무시
            untilCursorAndPop(arrList);
            if(!arrList.isEmpty()) {
                stack.push(arrList.remove(arrList.size()-1)); // arrList 뒤 stack에 담기
            }
            stack.push("C"); // cursor 푸쉬
            repairStack(arrList);

        } else if(charArr[0] == 'B' && indexOfCursor > 0 && indexOfCursor < stack.size()) { // 커서 왼쪽 문자를 삭제, 만약 커서가 문장 맨 앞이면 무시
            // dmihC dmiCh
            untilCursorAndPop(arrList); // stack: dmih dmi | arrList:
            stack.pop(); // dmi dm | arrList:
            stack.push("C"); // dmiC dmC | arrList:
            repairStack(arrList); // dmiC dmC | arrList:

        } else if(charArr[0] == 'P') {
            untilCursorAndPop(arrList);
            stack.push(String.valueOf(charArr[1])); // 문자 푸쉬
            stack.push("C"); // cursor 푸쉬
            repairStack(arrList);
        }
    }

    public static void untilCursorAndPop(ArrayList<String> arrList) {
        while(stack.peek() != "C") { // cursor 나올 때까지 반복
            arrList.add(stack.pop()); // pop하고 그 요소를 arrList에 저장. arrList 뒤가 곧 stack 앞
        }
        stack.pop(); // cursor 제거
    }

    public static void repairStack(ArrayList<String> arrList) {
        if(!arrList.isEmpty()) { // arrList가 비어있지 않다면
            for(int i=arrList.size()-1; i>=0; i--) {
                stack.push(arrList.remove(i)); // arrList 뒤에서부터 stack에 담기
            }
        }
    }
}

 

어찌저찌 풀긴 했는데 시간초과가 난다

그리고 코드가 너무 더러워 보인다

GPT한테 물어보니 Stack을 두개 운용한다

마치 물컵 두개를 가지고 이리저리 옮기는 것과 같다!

커서의 위치는 LeftStack과 RightStack의 경계선 자체이다!

package baekjoon;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Stack;

public class B1406 {
    static Stack<Character> leftStack = new Stack<>();
    static Stack<Character> rightStack = new Stack<>();

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        char[] charArr = br.readLine().toCharArray();

        for (char c : charArr) {
            leftStack.push(c);
        }

        int M = Integer.parseInt(br.readLine());

        for (int i = 0; i < M; i++) {
            String[] strArr = br.readLine().split(" "); // L, D, B, P $
            editor(strArr); // 경우에 따라 실행
        }

        // leftStack에서 꺼내면 반대순서로 꺼내지게 되기 때문에
        // rightStack으로 옮겨서 꺼내야 함
        StringBuilder sb = new StringBuilder();
        while (!leftStack.isEmpty()) { // leftStack 비어있지 않는 동안 반복
            rightStack.push(leftStack.pop());
        }
        while (!rightStack.isEmpty()) { // rightStack 비어있지 않는 동안 반복
            sb.append(rightStack.pop());
        }
        System.out.println(sb.toString());
    }

    public static void editor(String[] instruction) {
        switch (instruction[0]) {
            case "L":
                if (!leftStack.isEmpty()) { // leftStack 비어있지 않다면 (커서가 맨 앞이 아니라면)
                    rightStack.push(leftStack.pop()); // leftStack 하나 비워서 rightStack 으로 하나 옮기기 (커서를 왼쪽으로 한칸 옮김)
                }
                break;
            case "D":
                if (!rightStack.isEmpty()) { // rightStack 비어있지 않다면 (커서가 맨 뒤가 아니라면)
                    leftStack.push(rightStack.pop()); // rightStack 하나 비워서 rightStack 으로 하나 옮기기
                }
                break;
            case "B":
                if (!leftStack.isEmpty()) { // leftStack 비어있지 않다면 (커서가 맨 앞이 아니라면)
                    leftStack.pop(); // leftStack 하나 삭제
                }
                break;
            case "P":
                leftStack.push(instruction[1].charAt(0)); // stack의 지네릭이 Character라 charAt으로 캐스팅
                break;
        }
    }
}