관리 메뉴

LC Studio

백준 1406 에디터 (JAVA) 본문

Java/백준 알고리즘

백준 1406 에디터 (JAVA)

Leopard Cat 2022. 4. 28. 17:56

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

 

1406번: 에디터

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

www.acmicpc.net


풀이

요약하자면 한줄로 구성된 메모장을 만들라는 것이었다.

입력되는 아래의 조건에 따라 결과값을 반환하면 된다.

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

 

중간에 삽입과 삭제가 많은 경우다보니, 삽입과 삭제가 용이한 LinkedList를 활용하여 풀었다.

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.LinkedList;
import java.util.ListIterator;
import java.util.StringTokenizer;

public class Solution {
    public static void main(String[] args) throws IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        LinkedList<Character> list = new LinkedList<>();
        StringTokenizer st = null;

        // 초기 문자열 입력
        // 초기 문자열 LinkedList 형태로 저장
        String string = br.readLine();
        for(int i=0; i<string.length(); i++){
            list.add(string.charAt(i));
        }
        int M = Integer.parseInt(br.readLine());

        //iterator 메소드 호출 
		ListIterator<Character> iter = list.listIterator();
		//첫 커서 위치 조정
		while(iter.hasNext()) {
			iter.next();
		}
	
		for(int i=0; i<M; i++) {
			String command = br.readLine();
			char c = command.charAt(0);
			switch(c) {
                case 'L':
                    if(iter.hasPrevious())
                        iter.previous();

                    break;
                case 'D':
                    if(iter.hasNext())
                        iter.next();

                    break;
                case 'B':
                //previous로 리스트의 이전 요소를 반환한다.    
                //remove()는 next()나 previous()에 의해 반환된 가장 마지막 요소를 리스트에서 제거한다.
                    if(iter.hasPrevious()) {
                        iter.previous();
                        iter.remove();
                    }
                    break;
                case 'P':
                    char t = command.charAt(2);
                    iter.add(t);

                    break;
                default:
                    break;
			}
		}
		for(Character chr : list) {
			bw.write(chr);
		}
		
		bw.flush();
		bw.close(); 
	}
}

하지만... 결과는 시간초과... 

오랜만에 문제없이 해결했다고 기뻐했는데,,,ㅋㅋ 역시 뻔한 문제일리가 없다.

BufferedReader, Writer을 활용했지만 여전히 시간초과,

시간을 줄여야 한다.

이리저리 찾아보다, 다른 블로그에서 힌트를 얻었다.

https://minhamina.tistory.com/17

 

[백준 - Java] 1406번 : 에디터

문제 더보기 https://www.acmicpc.net/problem/1406 한 줄로 된 간단한 에디터를 구현하려고 한다. 이 편집기는 영어 소문자만을 기록할 수 있는 편집기로, 최대 600,000글자까지 입력할 수 있다. 이 편집기에

minhamina.tistory.com

https://minhamina.tistory.com/18

 

[Java] Iterator / ListIterator

Interface Iterator java.util Type Parameters : E - the type of elements returned by this iterator All Known Subinterfaces : ListIterator , XMLEventReader All Known Implementing Classes : BeanCon..

minhamina.tistory.com

바로 Listlterator을 활용하는 것이다!

ListIterator 인터페이스는 컬렉션 요소의 대체, 추가 그리고 인덱스 검색 등을 위한 작업에서 양방향으로 이동하는 것을 지원한다고 한다.

그 결과 처리 시간이 줄었다.

아래와 같이 해결하였다.

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.LinkedList;
import java.util.ListIterator;
import java.util.StringTokenizer;

public class Solution {
    public static void main(String[] args) throws IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        LinkedList<Character> list = new LinkedList<>();
        StringTokenizer st = null;

        // 초기 문자열 입력
        // 초기 문자열 LinkedList 형태로 저장
        String string = br.readLine();
        for(int i=0; i<string.length(); i++){
            list.add(string.charAt(i));
        }
        int M = Integer.parseInt(br.readLine());

        //iterator 메소드 호출 
		ListIterator<Character> iter = list.listIterator();
		//첫 커서 위치 조정
		while(iter.hasNext()) {
			iter.next();
		}
	
		for(int i=0; i<M; i++) {
			String command = br.readLine();
			char c = command.charAt(0);
			switch(c) {
                case 'L':
                    if(iter.hasPrevious())
                        iter.previous();

                    break;
                case 'D':
                    if(iter.hasNext())
                        iter.next();

                    break;
                case 'B':
                //previous로 리스트의 이전 요소를 반환한다.    
                //remove()는 next()나 previous()에 의해 반환된 가장 마지막 요소를 리스트에서 제거한다.
                    if(iter.hasPrevious()) {
                        iter.previous();
                        iter.remove();
                    }
                    break;
                case 'P':
                    char t = command.charAt(2);
                    iter.add(t);

                    break;
                default:
                    break;
			}
		}
		for(Character chr : list) {
			bw.write(chr);
		}
		
		bw.flush();
		bw.close(); 
	}
}
반응형

'Java > 백준 알고리즘' 카테고리의 다른 글

백준 3190 뱀 (JAVA)  (0) 2022.04.27
백준 1085 직사각형에서 탈출 (JAVA)  (0) 2022.03.23
백준 4948 베르트랑 공준 (JAVA)  (0) 2022.03.23
백준 1929 소수 구하기 (JAVA)  (0) 2022.03.22
백준 10757 큰 수 A+B (JAVA)  (0) 2022.03.21