Java - 알고리즘

백준 - 5397 키로거

TerianP 2022. 8. 22.
728x90

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

 

5397번: 키로거

첫째 줄에 테스트 케이스의 개수가 주어진다. 각 테스트 케이스는 한줄로 이루어져 있고, 강산이가 입력한 순서대로 길이가 L인 문자열이 주어진다. (1 ≤ L ≤ 1,000,000) 강산이가 백스페이스를 입

www.acmicpc.net

 


 

풀이 방법

실버 2 문제라서 그래도 할만할 줄 알고 편하게 도전했다가 망해버린 문제

처음에는 ArrayList 로 접근해서 풀어보려고 했는데 문제를 읽다보니까 이렇게 풀어서는 안되는구나...를 끝없이 느끼고 LinkList 로 전환하여서 풀었다.

 

솔직히 LinkList 를 Queue 구현할때만 사용하고, 심지어 List 의 다양한 기능을 위해 사용하는 ListIterator 는 처음 써보는 것이였어서 더욱 어렵게 느껴졌다.

 

다만 ListIterator  를 쓸수 있으면 금방 풀 수 있는 문제이기 때문에, 이번에는 풀이 과정 대신 해당 내용을 정리하고 넘어가겠다.

 

ListIterator<E> 인터페이스 란?

ListIterator 인터페이스는 iterator 인터페이스를 상속받아 여러 기능을 추가하여 기능을 제공하는 인터페이스로 List 인터페이스를 구현한 인스턴스(객체)에서 listiterator() 메서드를 사용해서 구현 가능하다!!

 

기본적으로 iterator 은 단방향으로만 이동이 가능하다 => 일반적인 queue 처럼 단방향으로만 진행된다.

반면, ListIterator  는 양방향으로 탐색하면서 List 에 내용을 검색, 추가, 삭제가 가능하다 => 키로거의 문제가 딱 여기에 맞는다. < > 에 따라서 List 를 이동하고 내용을 삭제, 추가 해야하기 때문!!

 

메서드 내용
void add(E e) 리스트의 nextindex() 위치에 e 를 추가한다
boolean hasNext() 리스트에 다음 데이터가 존재하면 true, 아니면 false 를 반환한다
boolean hasPrevious() 리스트에 이전 데이터가 존재하면 true, 아니면 false 를 반환한다.
E next() 리스트의 다음 데이터를 반환한 후 리스트 내 커서 위치를 다음 방향으로 이동한다
E previous() 리스트의 이전 데이터를 반환 후 리스트 내 커서 위치를 이전 방향으로 이동한다
int nextIndex() 현재 커서 기준 다음 index 를 반환한다 => 기본값 0
int previousIndex() 현재 커서 기준 이전 index 반환 => 기본값 -1
void remove() next(), previous() 로 반환된 가장 최근 데이터를 삭제한다.
void set(E e) next(), previous() 로 반환된 가장 최근 데이터를 추가한다.

 

나머지는 코드 주석 확인!

package baekJoon;

import java.io.*;
import java.util.*;

public class Quiz_5397 {
    static int T;
    // https://www.acmicpc.net/problem/5397
    // https://rays-space.tistory.com/44
    // https://godzz.tistory.com/11


    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));


        T = Integer.parseInt(br.readLine());

        for (int i = 0; i < T; i++) {
            String str = br.readLine();
            keyLogger(str);
        }

    }

    static void keyLogger(String str) throws IOException {

        List<Character> chArr = new LinkedList<Character>();
        ListIterator<Character> iter = chArr.listIterator();
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

        for (int i = 0; i < str.length(); i++) {
            switch (str.charAt(i)) {
                case '>':
                    // ListIterator 로 조사했을 때 만약 hasPrevious가 true 라면
                    // iter(커서) 를 한칸 뒤로 이동
                    if (iter.hasNext()) {
                        iter.next();
                    }
                    break;

                case '<':
                    // ListIterator 로 조사했을 때 만약 hasPrevious가 true 라면
                    // iter(커서) 를 한칸 뒤로 이동
                    if (iter.hasPrevious()) {
                        iter.previous();
                    }
                    break;

                case '-':
                    // 만약 - 를 만난다면 뒤로 갈 수 있는지 확인후
                    // 뒤로 이동한 뒤 previous() 로 반환된 가장 최근 데이터 삭제
                    if (iter.hasPrevious()) {
                        iter.previous();
                        iter.remove();
                    }
                    break;

                default:
                    // 위에 모두다 아니면 iter 에 i 값을 추가한다.
                    iter.add(str.charAt(i));
                    break;
            }
        }

        for (char c : chArr) {
            bw.write(c);
        }
        bw.write("\n");
        bw.flush();
    }
}

 

'Java - 알고리즘' 카테고리의 다른 글

백준 - 1922 네트워크 연결(feat. 크루스칼 알고리즘)  (0) 2022.08.24
백준 - 1712 손익분기점  (0) 2022.08.23
백준 - 2798 블랙잭  (0) 2022.08.21
백준 - 11652 카드  (0) 2022.08.20
백준 - 3055 탈출  (0) 2022.08.19

댓글