백준 문제 풀이/백준 (JAVA)

JAVA 백준 5397 키로거 (스택)

gamja00 2025. 6. 15. 17:34

 

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

 


문제

  1. 첫째 줄에 테스트 케이스의 개수 T 가 입력된다.
  2. 둘째 줄부터 T개의 줄에 길이가 L ( 1 <= L <= 1000000 )  인 문자열이 주어진다.
  3. 백스페이스를 입력했다면, '-'가 주어진다. 이때 커서의 바로 앞에 글자가 존재한다면, 그 글자를 지운다.
  4. 화살표의 입력은 '<'와 '>'로 주어진다. 이때는 커서의 위치를 움직일 수 있다면, 왼쪽 또는 오른쪽으로 1만큼 움직인다.
  5. 각 테스트 케이스에 대하여 비밀번호를 한 줄에 하나씩 출력하라.

 

 

정답 코드 (시간이 오래 걸림)

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

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

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

        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < T; i++) {
            String[] password = br.readLine().split("");

            Stack<String> left = new Stack<>();
            Stack<String> right = new Stack<>();

            for (int j = 0; j < password.length; j++) {
                if (Objects.equals(password[j], "<")) {
                    if (!left.isEmpty()) {
                        right.push(left.pop());
                    }
                } else if (Objects.equals(password[j], ">")) {
                    if (!right.isEmpty()) {
                        left.push(right.pop());
                    }
                } else if (Objects.equals(password[j], "-")) {
                    if (!left.isEmpty()) {
                        left.pop();
                    }
                } else {
                    left.push(password[j]);
                }
            }

            StringBuilder temp = new StringBuilder();

            while (!right.isEmpty()) {
                temp.append(right.pop());
            }
            temp.reverse();
            while (!left.isEmpty()) {
                temp.append(left.pop());
            }
            temp.reverse();

            sb.append(temp);
            if (i < T - 1) {
                sb.append("\n");
            }
        }
        System.out.println(sb);
    }
}

 

 

 

switch-case로 바꿔본 코드(정답, 더 느림)

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

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

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

        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < T; i++) {
            String[] password = br.readLine().split("");

            Stack<String> left = new Stack<>();
            Stack<String> right = new Stack<>();

            for (int j = 0; j < password.length; j++) {
                switch (password[j]) {
                    case "<":
                        if (!left.isEmpty()) {
                            right.push(left.pop());
                        }
                        break;
                    case ">":
                        if (!right.isEmpty()) {
                            left.push(right.pop());
                        }
                        break;
                    case "-":
                        if (!left.isEmpty()) {
                            left.pop();
                        }
                        break;
                    default:
                        left.push(password[j]);
                }
            }

            StringBuilder temp = new StringBuilder();

            while (!right.isEmpty()) {
                temp.append(right.pop());
            }
            temp.reverse();
            while (!left.isEmpty()) {
                temp.append(left.pop());
            }
            temp.reverse();

            sb.append(temp);
            if (i < T - 1) {
                sb.append("\n");
            }
        }
        System.out.println(sb);
    }
}

 

 

 

시간이 짧은 사람의 코드와 비교했을 때 두 배 이상 차이가 나는데,

다른 사람의 코드를 찾아보니 Listiterator를 사용하여 코드를 만든 듯 했다.

 

시간이 더 짧은 코드를 원한다면 Listiterator를 사용한 코드를 써도 될 것 같다.