[백준] 1406번 에디터 JAVA (자바) 풀이
문제 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
* 독학으로 익히는 코딩이라 틀린 것이 있을 수 있습니다. 오류가 있다면 댓글을 통해 알려주세요. 감사합니다. *