문제
정수를 저장하는 스택을 구현한 다음, 입력으로 주어지는 명령을 처리하는 프로그램을 작성하시오.
명령은 총 다섯 가지이다.
- push X: 정수 X를 스택에 넣는 연산이다.
- pop: 스택에서 가장 위에 있는 정수를 빼고, 그 수를 출력한다. 만약 스택에 들어있는 정수가 없는 경우에는 -1을 출력한다.
- size: 스택에 들어있는 정수의 개수를 출력한다.
- empty: 스택이 비어있으면 1, 아니면 0을 출력한다.
- top: 스택의 가장 위에 있는 정수를 출력한다. 만약 스택에 들어있는 정수가 없는 경우에는 -1을 출력한다.
입력
첫째 줄에 주어지는 명령의 수 N (1 ≤ N ≤ 10,000)이 주어진다. 둘째 줄부터 N개의 줄에는 명령이 하나씩 주어진다. 주어지는 정수는 1보다 크거나 같고, 100,000보다 작거나 같다. 문제에 나와있지 않은 명령이 주어지는 경우는 없다.
출력
출력해야 하는 명령이 주어질 때마다, 한 줄에 하나씩 출력한다.
문제 접근 방법
이번 문제는 스택의 기본적인 작동 원리를 알고 있는지 물어보는 문제이다.
첫 줄에서 명령의 입력 개수를 받고 그 수만큼 명령을 입력받으면 된다.
명령의 입력은 한 줄로 명령 단어와 그 뒤에 숫자가 들어오는데 push명령의 경우에만 뒤에 숫자가 공백을 기준으로 구분되어 들어오므로 어떤 명령이 입력으로 들어왔는지 판단도 해줘야 한다.
따라서 push명령의 경우에는 입력을 한번 더 받아 push 할 값을 받아와야 한다는 뜻이고 나머지 명령의 경우에는 명령 단어만 입력된다는 의미이다.
따라서 나는 알아보기 쉽게 if-else문보다는 switch문을 사용하여 입력되는 명령을 수행할 예정이다.
이때, 문제에서도 나왔듯 주의해야 할 점은 스택이 비었는데 pop명령이 들어왔다고 명령을 실행해버리면 에러가 뜬다. 따라서 pop명령의 경우에는 먼저 스택이 비어있는지 아닌지 상태부터 판단해주어 비어있으면 명령을 실행하지 않고 -1을 출력해서 끝내야 한다.
이번 문제는 입출력 양이 조금 많기도 하고 시간제한도 힘들기 때문에 입력 함수와 출력 함수를 비교해서 성능 차이도 확인해보겠다.
- BufferedReader + BufferedWriter
- BufferedReader + System.out.println()
- Scanner + BufferedWriter
- Scanner + System.out.println()
JAVA 코드 풀이
- BufferedReader + BufferedWriter
import java.util.*;
import java.io.*;
public class Main {
public static void main(String args[]) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
Stack<String> stack = new Stack<>(); // 스택 선언
int remoteNum = Integer.parseInt(br.readLine()); // 명령 개수 입력
while(remoteNum-- > 0){
StringTokenizer st = new StringTokenizer(br.readLine());
switch(st.nextToken()){ // 입력된 명령이 어떤 명령인지 판단
case "push":
stack.push(st.nextToken()); // push 뒤에 입력된 수를 스택에 추가
break;
case "pop":
if(stack.isEmpty()) // 스택이 비어있으면 pop명령 실행하지 않고 -1출력
bw.write("-1\n");
else // 스택이 비어있지 않으면 최상단 값 꺼내 출력
bw.write(stack.pop()+"\n");
break;
case "size": // 스택에 들어있는 원소의 갯수 출력
bw.write(String.valueOf(stack.size())+"\n");
break;
case "empty": // 스택이 비어있는지 아닌지 출력
if(stack.isEmpty())
bw.write("1\n");
else
bw.write("0\n");
break;
case "top": // 스택의 최상단 원소를 제거하지 않고 읽어오기만 한다
if(stack.isEmpty()) // 스택이 비어있으면 -1출력
bw.write("-1\n");
else
bw.write(stack.peek()+"\n");
break;
}
}
bw.close();
}
}
- BufferedReader + System.out.println()
import java.util.*;
import java.io.*;
public class Main {
public static void main(String args[]) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
Stack<String> stack = new Stack<>();
int remoteNum = Integer.parseInt(br.readLine());
while(remoteNum-- > 0){
StringTokenizer st = new StringTokenizer(br.readLine());
switch(st.nextToken()){
case "push":
stack.push(st.nextToken());
break;
case "pop":
if(stack.isEmpty())
System.out.println(-1);
else
System.out.println(stack.pop());
break;
case "size":
System.out.println(stack.size());
break;
case "empty":
if(stack.isEmpty())
System.out.println(1);
else
System.out.println(0);
break;
case "top":
if(stack.isEmpty())
System.out.println(-1);
else
System.out.println(stack.peek());
break;
}
}
}
}
- Scanner + BufferedWriter
import java.util.*;
import java.io.*;
public class Main {
public static void main(String args[]) throws IOException{
Scanner input = new Scanner(System.in);
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
Stack<Integer> stack = new Stack<>();
int remoteNum = input.nextInt();
while(remoteNum-- > 0){
switch(input.next()){
case "push":
stack.push(input.nextInt());
break;
case "pop":
if(stack.isEmpty())
bw.write("-1\n");
else
bw.write(stack.pop()+"\n");
break;
case "size":
bw.write(stack.size()+"\n");
break;
case "empty":
if(stack.isEmpty())
bw.write("1\n");
else
bw.write("0\n");
break;
case "top":
if(stack.isEmpty())
bw.write("-1\n");
else
bw.write(stack.peek()+"\n");
break;
}
}
bw.close();
}
}
- Scanner + System.out.println()
import java.util.*;
public class Main {
public static void main(String args[]) {
Scanner input = new Scanner(System.in);
Stack<Integer> stack = new Stack<>();
int remoteNum = input.nextInt();
while(remoteNum-- > 0){
switch(input.next()){
case "push":
stack.push(input.nextInt());
break;
case "pop":
if(stack.isEmpty())
System.out.println(-1);
else
System.out.println(stack.pop());
break;
case "size":
System.out.println(stack.size());
break;
case "empty":
if(stack.isEmpty())
System.out.println(1);
else
System.out.println(0);
break;
case "top":
if(stack.isEmpty())
System.out.println(-1);
else
System.out.println(stack.peek());
break;
}
}
}
}
코드 실행 결과
후기
이번 문제는 스택의 함수를 익히기 위한 문제로 적절한 문제인 것 같다. 스택을 막 배웠을 때 풀면 좋을 듯 한 스택의 기초를 물어보는 문제라고 생각한다. 각 명령마다 입력의 개수가 다르고, 스택의 상태를 먼저 고려해서 명령을 실행할지 말지도 결정해서 스택의 함수의 사용법을 익히는 좋은 문제인 것 같다.
+ 시간이 힘들게 걸려있으면 Scanner, System.out.println() 함수보다는 BufferedReader, BufferedWriter함수를 사용하는 것이 시간제한에 입출력 때문에 걸릴 염려가 없는 것 같다.
문제 원본
'문제 풀이 > [JAVA_자바] 백준' 카테고리의 다른 글
[JAVA / 자바] 백준 1874번 - 스택 수열 (0) | 2022.01.17 |
---|---|
[JAVA / 자바] 백준 10816 - 숫자 카드 2 (0) | 2022.01.14 |
[JAVA / 자바] 백준 1181번 - 단어 정렬 (0) | 2022.01.12 |
[JAVA / 자바] 백준 10814번 - 나이순 정렬 (0) | 2022.01.11 |
[JAVA / 자바] 백준 9012번 - 괄호 (0) | 2022.01.10 |