본문 바로가기
Baekjoon/[1] 자료구조

[백준] 1406번 에디터 JAVA (자바) 풀이

by Poorm 푸름 2023. 6. 20.

문제 1406번

명령어
   L    커서를 왼쪽으로 한 칸 옮김 (커서가 문장 맨 앞이면 무시)
   D    커서를 오른쪽으로 한 칸 옮김 (커서가 문장 맨 뒤이면 무시)
   B    커서 왼쪽에 있는 문자를 삭제함 (커서가 문장 맨 앞이면 무시)
   삭제로 인해 커서는 한 칸 왼쪽으로 이동한 것처럼 나타나지만
   실제로 커서의 오른쪽에 있던 문자는 그대로
   P$    $라는 문자를 커서 왼쪽에 추가함

: 위와 같은 명령어를 사용하여 문자열 수정하기 (처음에는 커서가 맨 뒤에 있다)

 

 [입력]

 

 : 첫째 줄에는 문자열이 주어진다

 : 두번째 줄에는 명령어 개수 M이다

 : 셋째 줄부터 M개의 줄에 걸쳐 입력할 명령어가 순서대로 주어진다

 

 [출력]


 : 첫째 줄에 모든 명령어를 수행하고 문자열 출력하기

 

 

 [문제이해]


 : 커서는 좌우로 자유롭게 이동할 수 있다
 : 커서를 기준으로 좌측 문자들과 우측 문자들을 각각 다른 스택에 넣어준다

  (예)

  * 커서 = |

  문자열 LOVE | (커서는 맨뒤에 존재) → 왼쪽스택에 문자열 다 넣고 시작하기

  명령1 : L = LOV | E → 왼쪽 스택에서 E 빼서 오른쪽 스택에 넣기

  명령2 : P A = LOVA | E → 왼쪽 스택에 A 문자 추가

 

 

 [스택 연산]

 

  init()  스택을 초기화
  create()  스택을 생성
  is_empty(s)  스택이 비어있는지 검사
  is_full(s)  스택이 가득 찼는지 검사 
  push(e)  스택의 맨 위에 요소 e 추가
  pop(s)  스택의 맨 위 요소를 삭제
  peek(s)  스택의 맨 위 요소를 삭제하지 않고 반환
  top()  스택 맨 위에 있는 데이터 값 반환
  push()  스택에 데이터 삽입
  pop()  스택에서 데이터 삭제하여 반환
  isEmpty()  스택에 원소가 없으면 'True', 있으면 'False' 값 반환
  isFull()  스택에 원소가 없으면 'False', 있으면 'True' 값 반환

 

 [코드]

import java.io.*;
import java.util.*;
 public class Main{
     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 str = br.readLine();
           int M = Integer.parseInt(br.readLine());
           
           Stack<Character> left = new Stack<>();
           Stack<Character> right = new Stack<>();
           StringBuilder sb = new StringBuilder();
           
           for(int i=0; i<str.length(); i++){
                     left.push(charAt(i));
           }
           
           while(M-->0){
             String s = br.readLine();
          
             switch(s.charAt(0)){
           
             case 'L':
               if(!left.isEmpty()){
                 right.push(left.pop());
               }
             
             case 'D':
               if(!right.isEmpty()){
                 left.push(right.pop());
               }
             
             case 'B':
                if(!left.isEmpty()){
                  left.pop();
                }
              
             case 'P':
                left.push(s.charAt(2));
             }   
           }
          
           while(!left.isEmpty()){ 
                right.push(left.pop()); 
           }                          
           while(!right.isEmpty()){
                bw.write(right.pop()); 
           }
        bw.flush();
    }
}

 

 [해설]

 

:  String str = br.readLine(); 첫줄에 문자열 입력받기

:  int M = Integer.parseInt(br.readLine()); 둘째줄에 명령 개수 M 입력받기
           
:  Stack<Character> left = new Stack<>(); 커서를 기준으로 왼쪽 스택
 
:  Stack<Character> right = new Stack<>(); 커서를 기준으로 오른쪽 스택

 :  for(int i=0; i<str.length(); i++){
                     left.push(charAt(i));
     } 첫줄에 입력받은 문자열 길이만큼 왼쪽스택에 다 넣고 시작 (커서가 맨 뒤에 있으니까 왼쪽에만 문자열있다)
           
  :  String s = br.readLine(); 셋째줄부터 명령어 입력받기
          
  :  switch(s.charAt(0)){ 명령어 문자열 중에 0번째 문자랑 case의 문자랑 비교하기
           
  :  case 'L':
         if(!left.isEmpty()){
            right.push(left.pop());
          } 왼쪽 스택이 비어있지 않다면 왼쪽 스택에 있는 문자 빼서 오른쪽 스택에 넣기
             
   :  case 'D':
          if(!right.isEmpty()){
             left.push(right.pop());
           } 오른쪽 스택이 비어있지 않다면 오른쪽 스택에 있는 문자 빼서 왼쪽 스택에 넣기
             
    :  case 'B':
           if(!left.isEmpty()){
              left.pop();
            } 왼쪽 스택이 비어있지 않다면 왼쪽 스택의 문자 삭제
              
     :  case 'P':                           
            left.push(s.charAt(2)); 

       입력받은 명령어 2번째 문자 왼쪽 스택에 추가하기
       공백도 문자로 취급 (P A 라면 charAt(0)=P, charAt(1)= , charAt(2)=A)
                 
     :  while(!left.isEmpty()){ 
            right.push(left.pop()); 한쪽 스택에 모두 몰아서 한번에 출력하기
           }    
                      

       오른쪽 스택으로 모는 이유는 왼쪽 스택으로 몰면 pop할 때 문자가 거꾸로 출력되기 때문에

       마지막에 reverse를 따로 해줘야 한다

       하지만 왼쪽 스택에서 빼서 오른쪽 스택에 넣으면 거꾸로된 순서로 넣었기 때문에

       나중에 오른쪽 스택을 다시 pop하면 정상적으로 출력된다


      :  while(!right.isEmpty()){
              bw.write(right.pop()); 오른쪽 스택 pop해서 출력
           }                       

 

 

                                                         

이제 풀어보러 갈께요 :)

 

 

https://www.acmicpc.net/problem/1406

 

1406번: 에디터

첫째 줄에는 초기에 편집기에 입력되어 있는 문자열이 주어진다. 이 문자열은 길이가 N이고, 영어 소문자로만 이루어져 있으며, 길이는 100,000을 넘지 않는다. 둘째 줄에는 입력할 명령어의 개수

www.acmicpc.net

 

 

* 독학으로 익히는 코딩이라 틀린 것이 있을 수 있습니다. 오류가 있다면 댓글을 통해 알려주세요. 감사합니다. *