-문제 링크 : https://www.acmicpc.net/problem/1406
- 문제 해결 :
이 문제는 정해진 명령어가 주어지고, 명령어에 맞게 문자열에 변화를 주어
출력하는 문제이다.
문제 조건은
- 초기 커서는 문자열의 오른쪽 끝에 위치한다.
- L - 커서를 왼쪽으로 한 칸 옮김 (커서가 문장의 맨 앞이면 무시됨)
- D - 커서를 오른쪽으로 한 칸 옮김 (커서가 문장의 맨 뒤이면 무시됨)
- B - 커서 왼쪽에 있는 문자를 삭제함 (커서가 문장의 맨 앞이면 무시됨)
삭제로 인해 커서는 한 칸 왼쪽으로 이동한 것처럼 나타나지만, 실제로 커서의 오른쪽에 있던 문자는 그대로임- 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();
}
}