본문 바로가기
Algorithm

[백준 Silver 3] 5397 키로거 - Java

by Ray 2021. 12. 18.

문제링크 : https://www.acmicpc.net/problem/5397

 

5397번: 키로거

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

www.acmicpc.net

 

접근 과정 : 

  • 화살표로 인한 인덱스 변화에 주목하면서, 패스워드를 입력하면 된다고 생각
  • 자료구조로, 연결리스트나 스택을 사용할 수 있을 것이라 생각
  • 최근 ListIterator를 알게되었고, 연결리스트의 탐색에 필요한 비용을 줄여주기에 이를 사용!!
  • vs 스택을 사용하는 경우도 비교해보았다.

 

소스 코드 및 결과 : 

package BOJ;

/*
    키로거 
    
    LinkedList + ListIterator
*/

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

public class BOJ5397 {

    public static void main(String[] args) throws NumberFormatException, IOException {

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

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

        StringBuilder result = new StringBuilder();

        while (T-- > 0) {
            String input = br.readLine();
            List<Character> inputList = new LinkedList<>();
            ListIterator<Character> inputIter = inputList.listIterator();

            for (int i = 0; i < input.length(); i++) {
                switch (input.charAt(i)) {
                    case '<':
                        if (inputIter.hasPrevious()) {
                            inputIter.previous();
                        }

                        break;
                    case '>':
                        if (inputIter.hasNext()) {
                            inputIter.next();
                        }

                        break;
                    case '-':

                        if (inputIter.hasPrevious()) {
                            inputIter.previous();
                            inputIter.remove();
                        }
                        break;

                    default:

                        inputIter.add(input.charAt(i));
                        break;
                }
            }

            for (char c : inputList) {
                result.append(c);
            }
            result.append("\n");
        }

        System.out.println(result.toString().trim());
    }
}

 

/*
    키로거 
    
    Stack 2개
    (커서를 기준으로 앞부분과 뒷부분을 의미)

*/

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

public class Main {

    public static void main(String[] args) throws NumberFormatException, IOException {

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

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

        StringBuilder result = new StringBuilder();

        while (T-- > 0) {
            String input = br.readLine();

            Stack<Character> front = new Stack<>();
            Stack<Character> back = new Stack<>();

            for (int i = 0; i < input.length(); i++) {
                switch (input.charAt(i)) {
                    case '<':

                        if (!front.isEmpty()) {
                            back.add(front.pop());
                        }

                        break;
                    case '>':
                        if (!back.isEmpty()) {
                            front.add(back.pop());
                        }

                        break;
                    case '-':
                        if (!front.isEmpty()) {
                            front.pop();
                        }
                        break;

                    default:
                        front.add(input.charAt(i));

                        break;
                }
            }

           StringBuilder temp = new StringBuilder();

            while (!front.isEmpty()) {
                temp.append(front.pop());
            }
            result.append(temp.reverse());
            while (!back.isEmpty()) {
                result.append(back.pop());
            }
            result.append("\n");

        }

        System.out.println(result.toString().trim());
    }
}

 

 

/*

    키로거 
    
    Deque / Stack
    
*/

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

public class Main {

    public static void main(String[] args) throws NumberFormatException, IOException {

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

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

        StringBuilder result = new StringBuilder();

        while (T-- > 0) {
            String input = br.readLine();

            Deque<Character> front = new LinkedList<>();
            Stack<Character> back = new Stack<>();

            for (int i = 0; i < input.length(); i++) {
                switch (input.charAt(i)) {
                    case '<':

                        if (!front.isEmpty()) {
                            back.add(front.pollLast());
                        }

                        break;
                    case '>':
                        if (!back.isEmpty()) {
                            front.addLast(back.pop());
                        }

                        break;
                    case '-':
                        if (!front.isEmpty()) {
                            front.removeLast();
                        }
                        break;

                    default:
                        front.addLast(input.charAt(i));

                        break;
                }
            }


            while (!front.isEmpty()) {
                result.append(front.pollFirst());
            }
            while (!back.isEmpty()) {
                result.append(back.pop());
            }
            result.append("\n");

        }

        System.out.println(result.toString().trim());
    }
}

 

P.S

LinkedList+ListIterator < Deque + Stack < Stack+Stack 순으로 더 많은 시간을 소비하였다.

ListIterator 를 통해 LinkedList의 탐색 속도를 줄인것이 주요했다.

(LinkedList의 삽입,삭제는 O(1)이지만, 해당 노드를 탐색하는데 O(N)를 필요로 한다.!!!)

 

더 빠른 속도를 보여주는 다름 사람들은 클래스르 새로 만들거나, 배열을 2개 사용해서 인덱스만 관리한 것 같다.