[백준] 에디터

김현진·2022년 1월 19일
0

코테준비

목록 보기
18/22

-문제 링크 : https://www.acmicpc.net/problem/1406

  • 문제 해결 :
    이 문제는 정해진 명령어가 주어지고, 명령어에 맞게 문자열에 변화를 주어
    출력하는 문제이다.
    문제 조건은
  1. 초기 커서는 문자열의 오른쪽 끝에 위치한다.
  2. L - 커서를 왼쪽으로 한 칸 옮김 (커서가 문장의 맨 앞이면 무시됨)
  3. D - 커서를 오른쪽으로 한 칸 옮김 (커서가 문장의 맨 뒤이면 무시됨)
  4. B - 커서 왼쪽에 있는 문자를 삭제함 (커서가 문장의 맨 앞이면 무시됨)
    삭제로 인해 커서는 한 칸 왼쪽으로 이동한 것처럼 나타나지만, 실제로 커서의 오른쪽에 있던 문자는 그대로임
  5. P $ - $ 라는 문자를 커서 왼쪽에 추가함

    처음에는 명령어를 수행할 때 커서를 움직이는 방향으로 생각해서, 각 문자열 사이에 빈칸을 만들어 두고 그 곳에 커서를 놓는 방식으로 시도해 보았다. 또 이 방식으로
    하게 되면 크기가 동적으로 변하기 때문에 arraylist를 사용하여 구현해 보았다.
    예를 들면, abcd문자열이 주어져 있을 때 ㅁaㅁbㅁcㅁdㅁ 이렇게 만들어 두고
    커서의 위치를 맨 뒤로 초기화 한 뒤, 커서의 이동이면 커서의 위치를 변경해 주고,
    문자의 삽입, 삭제면 arraylist에서 삭제를 하는 식으로 구현을 하였다.
    그런데 시간초과가 떠서 다른 방법을 생각해 보았다.

    이번에는 커서를 중심으로 생각해 보았다.
    커서를 기준으로,
    L -> 커서의 왼쪽에 있는 문자중 제일 가까운 글자를 오른쪽으로 넘김
    D -> 커서의 오른쪽에 있는 문자중 제일 가까운 글자를 왼쪽으로 넘김
    B -> 커서의 왼쪽에 있는 문자중 제일 가까운 글자를 삭제함
    P $-> 커서의 왼쪽에 있는 문자중 제일 가까운 글자에 $를 추가함

    예를 들면, abcd가 주어졌을 때 처음에는
    R-[a,b,c,d] / L-[]
    P x를 수행하면
    R-[a,b,c,d,x] / L-[]
    L을 수행하면
    R-[a,b,c,d] / L-[x]
    P y를 수행하면
    R-[a,b,c,d,y] / L-[x]

    또한 이 방식에서, 가장 중요하게 생각한 것은 명령어에서 '제일 가까운 글자'라는 말이었다.
    오른쪽이든, 왼쪽이든 가장 가까운 글자가 영향을 받았기 때문에 각 왼쪽 오른쪽의 문자들을 담는 자료구조로 스택을 사용하기로 했다.
    스택을 사용한다면, leftStack과 rightStack을 나누고,
    처음에는 모든 글자를 순서대로 leftStack에 넣어두고
    L -> leftStack에서 pop -> rightStack에 push
    D -> rightStack에서 pop -> leftStack에 push
    B -> leftStack에서 pop
    P -> leftStack에 push
    이런 방식으로 구현하면 되었다.
public class BJ1406 {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

        String s = br.readLine();

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

        Stack<Character> leftStack = new Stack<>(); //왼쪽 스택
        Stack<Character> rightStack = new Stack<>(); //오른쪽 스택

        for(int i=0;i<s.length();i++){
            leftStack.push(s.charAt(i)); //왼쪽 스택에 모두 푸쉬
        }

        for(int i=0;i<N;i++){

            String [] strs = br.readLine().split(" ");

            if("P".equals(strs[0])){ //P일때
                leftStack.push(strs[1].charAt(0));
            }else if("L".equals(strs[0])){ //L일때
                if(leftStack.empty()) continue;
                rightStack.push(leftStack.pop());
            }else if("B".equals(strs[0])){ //B일때
                if(leftStack.empty()) continue;
                leftStack.pop();
            }else{ //D일때
                if(rightStack.empty()) continue;
                leftStack.push(rightStack.pop());
            }
        }


        if(!leftStack.empty()){ //비어있는지 확인 후 오른쪽으로 모두 넘겨줌
        			//출력할때 편하게 하기 위해
            while(!leftStack.empty()){
                rightStack.push(leftStack.pop());
            }
        }

        if(!rightStack.empty()){ //bufferedWriter에 차례로 저장
            while(!rightStack.empty()){
                bw.write(rightStack.pop());
            }
        }

        bw.flush();
        bw.close();
    }
}

0개의 댓글