문제
정수를 저장하는 스택을 구현한 다음, 입력으로 주어지는 명령을 처리하는 프로그램을 작성하시오.
명령은 총 다섯 가지이다.
push X: 정수 X를 스택에 넣는 연산이다.pop: 스택에서 가장 위에 있는 정수를 빼고, 그 수를 출력한다. 만약 스택에 들어있는 정수가 없는 경우에는 -1을 출력한다.size: 스택에 들어있는 정수의 개수를 출력한다.empty: 스택이 비어있으면 1, 아니면 0을 출력한다.top: 스택의 가장 위에 있는 정수를 출력한다. 만약 스택에 들어있는 정수가 없는 경우에는 -1을 출력한다.
입력
첫째 줄에 주어지는 명령의 수 N (1 ≤ N ≤ 10,000)이 주어진다. 둘째 줄부터 N개의 줄에는 명령이 하나씩 주어진다. 주어지는 정수는 1보다 크거나 같고, 100,000보다 작거나 같다. 문제에 나와있지 않은 명령이 주어지는 경우는 없다.
출력
출력해야하는 명령이 주어질 때마다, 한 줄에 하나씩 출력한다.

답안
import java.io.BufferedReader
import java.io.BufferedWriter
import java.io.InputStreamReader
import java.io.OutputStreamWriter
import java.util.Stack
import java.util.StringTokenizer
fun main() {
val bufferedReader = BufferedReader(InputStreamReader(System.`in`))
val bufferedWriter = BufferedWriter(OutputStreamWriter(System.out))
val stack = Stack<Int>()
repeat(bufferedReader.readLine().toInt()) {
val str = StringTokenizer(bufferedReader.readLine())
when (str.nextToken()) {
"push" -> stack.push(str.nextToken().toInt())
"pop" -> bufferedWriter.write(
(if (stack.isEmpty()) -1 else stack.pop()).toString() + "\n"
)
"size" -> bufferedWriter.write(
stack.size.toString() + "\n"
)
"empty" -> bufferedWriter.write(
(if (stack.isEmpty()) 1 else 0).toString() + "\n"
)
"top" -> bufferedWriter.write(
(if (stack.isEmpty()) -1 else stack.peek()).toString() + "\n"
)
}
}
bufferedReader.close()
bufferedWriter.flush()
}
풀이
세부 구현 방법
- BufferedReader로 첫 줄을 읽어 명령의 수 N을 저장한다.
- repeat(N)을 사용하여 N번 반복하면서 매 줄마다 명령어를 입력받는다.
- StringTokenizer로 입력을 구분하고, when문으로 명령어를 분기 처리한다.
- 명령어별로 Stack의 push, pop, size, isEmpty, peek 메서드를 적절히 사용한다.
- pop, top, empty, size 명령에 대한 결과는 반드시 BufferedWriter.write()로 출력한다.
- 입력 처리가 모두 끝난 후 bufferedReader.close()로 입력 스트림을 닫고, bufferedWriter.flush()로 출력 스트림을 비워 출력한다.
주의사항 및 성능 포인트
- Scanner, println 대신 BufferedReader, BufferedWriter를 사용하여 대량 입출력에 대비했다.
- pop이나 top을 수행할 때, 스택이 비어 있는지 반드시 isEmpty()로 체크한 후 동작하도록 구현했다.
- 매 출력마다 flush()를 하지 않고, 마지막에 flush()를 한 번만 호출하여 성능을 최적화했다.
- StringTokenizer를 사용하여 명령어와 숫자를 빠르게 분리했다.
기본 개념 정리
Stack
- LIFO(Last In, First Out) 구조를 가진 자료구조이다.
- 즉, 가장 나중에 들어온 데이터가 가장 먼저 나간다.
- Kotlin에서는 기본적으로 java.util.Stack 클래스를 사용한다.
- 내부적으로 Vector 기반으로 동작한다 (자동으로 크기가 조절되는 배열)
push(x: Int)
- 스택에 정수 x를 맨 위에 추가(push) 한다.
- 추가할 때 별다른 제약 없이 바로 삽입된다.
- 시간 복잡도: O(1) (항상 빠르게 추가)
pop()
- 스택의 맨 위에 있는 요소를 제거하고 반환(pop) 한다.
- 만약 스택이 비어있으면 EmptyStackException이 발생할 수 있다.
- 안전하게 사용하려면 isEmpty() 체크 후 사용하는 것이 좋다.
- 시간 복잡도: O(1)
peek()
- 스택의 맨 위 요소를 제거하지 않고 반환(조회) 한다.
- 스택은 그대로 유지된다.
- 비어있을 경우 EmptyStackException이 발생할 수 있으니 isEmpty() 체크 필요.
- 시간 복잡도: O(1)
isEmpty()
- 스택이 비어있으면 true, 하나라도 요소가 있으면 false를 반환한다.
- 주로 pop(), peek()를 사용하기 전에 안전하게 확인하는 데 쓰인다.
size
- 스택에 현재 들어있는 요소의 개수를 반환한다.
- stack.size처럼 프로퍼티(변수) 형태로 바로 접근 가능하다.
- 시간 복잡도: O(1)
'🌀알고리즘🌀' 카테고리의 다른 글
| [알고리즘] 동적 계획법(Dynamic Programming, DP) (0) | 2025.05.06 |
|---|---|
| [프로그래머스] 기능개발 (Kotlin) (0) | 2025.04.29 |
| [백준/1822] 차집합 (Kotlin) (1) | 2025.04.29 |
| [백준/10845] 큐 (Kotlin) (0) | 2025.04.28 |
| [백준/15552] 빠른 A+B (Kotlin) (1) | 2025.04.28 |