LinkedList 백준 알고리즘 자바 1406 ‘에디터’ 문제풀이

1 minute read

Problem

한 줄로 된 간단한 에디터를 구현하려고 한다. 이 편집기는 영어 소문자만을 기록할 수 있는 편집기로, 최대 600,000글자까지 입력할 수 있다. 이 편집기에는 ‘커서’라는 것이 있는데, 커서는 문장의 맨 앞(첫 번째 문자의 왼쪽), 문장의 맨 뒤(마지막 문자의 오른쪽), 또는 문장 중간 임의의 곳(모든 연속된 두 문자 사이)에 위치할 수 있다. 즉 길이가 L인 문자열이 현재 편집기에 입력되어 있으면, 커서가 위치할 수 있는 곳은 L+1가지 경우가 있다. 이 편집기가 지원하는 명령어는 다음과 같다.

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

초기에 편집기에 입력되어 있는 문자열이 주어지고, 그 이후 입력한 명령어가 차례로 주어졌을 때, 모든 명령어를 수행하고 난 후 편집기에 입력되어 있는 문자열을 구하는 프로그램을 작성하시오. 단, 명령어가 수행되기 전에 커서는 문장의 맨 뒤에 위치하고 있다고 한다.

Input
첫째 줄에는 초기에 편집기에 입력되어 있는 문자열이 주어진다. 이 문자열은 영어 소문자로만 이루어져 있으며, 길이는 100,000을 넘지 않는다. 둘째 줄에는 입력할 명령어의 개수를 나타내는 정수 N(1≤N≤500,000)이 주어진다. 셋째 줄부터 N개의 줄에 걸쳐 입력할 명령어가 순서대로 주어진다. 명령어는 위의 네 가지 중 하나의 형태로만 주어진다.

Output
첫째 줄에 모든 명령어를 수행하고 난 후 편집기에 입력되어 있는 문자열을 출력한다.

Solution

  • 링크드리스트 문제라고 정말 링크드리스트를 사용하면 ‘시간초과’가 된다.
  • Scanner 보다 BufferedReader가 훨씬 빠르다. (약 6배 정도!)
  • 이것저것 다 해봤는데, 스택으로 풀어야 시간초과가 되지 않는다. 커서가 움직이는 것을 2개의 스택을 이용해, 커서가 가리키는 곳이 lStack(왼쪽 스택)의 마지막이 되도록 하면 된다!

Code

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Stack;
public class Main {
	public static void main(String[] args) throws IOException {
		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
		StringBuilder str = new StringBuilder(reader.readLine());
		int n = Integer.parseInt(reader.readLine());
		
		Stack lStack = new Stack<>();
		Stack rStack = new Stack<>();
		for(int i = 0; i < str.length(); i++)
			lStack.add(str.charAt(i));
		
		while(n-- > 0) {
			String cmd = reader.readLine();

			if(cmd.contains("P"))
				lStack.add(cmd.charAt(2));
			else {
				switch(cmd) {
				case "L": 
					if(!lStack.isEmpty())
						rStack.add(lStack.pop());
					break;
				case "D": 
					if(!rStack.isEmpty())
						lStack.add(rStack.pop());
					break;
				case "B": 
					if(!lStack.isEmpty())
						lStack.pop();
					break;
				}
			}
		}
		while(!lStack.isEmpty()) rStack.add(lStack.pop());
		while(!rStack.isEmpty()) System.out.print(rStack.pop());
	}
}

Tags:

Updated: