[boj] 10828 - 스택 Kotlin 풀이 (배열 사용)
10828
문제
정수를 저장하는 스택을 구현한 다음, 입력으로 주어지는 명령을 처리하는 프로그램을 작성하시오.
명령은 총 다섯 가지이다.
push X: 정수 X를 스택에 넣는 연산이다.
pop: 스택에서 가장 위에 있는 정수를 빼고, 그 수를 출력한다. 만약 스택에 들어있는 정수가 없는 경우에는 -1을 출력한다.
size: 스택에 들어있는 정수의 개수를 출력한다.
empty: 스택이 비어있으면 1, 아니면 0을 출력한다.top: 스택의 가장 위에 있는 정수를 출력한다. 만약 스택에 들어있는 정수가 없는 경우에는 -1을 출력한다.
입력
첫째 줄에 주어지는 명령의 수 N (1 ≤ N ≤ 10,000)이 주어진다. 둘째 줄부터 N개의 줄에는 명령이 하나씩 주어진다. 주어지는 정수는 1보다 크거나 같고, 100,000보다 작거나 같다. 문제에 나와있지 않은 명령이 주어지는 경우는 없다.
출력
출력해야하는 명령이 주어질 때마다, 한 줄에 하나씩 출력한다.
풀이 방법
Null을 포함한 배열과, 배열의 마지막을 가르키는 pointer 전역변수를 선언해서 포인터를 이용한 스택을 구현하였다.
우선 두가지 에로사항이 있었는데
1. 반복문이 제 멋대로 한바퀴 도는 문제
처음 작성한 코드의 경우 Scanner의 nextInt()를 사용하여 반복 횟수를 지정 받았는데,
이 과정에서 개행문자 '\n'이 섞여 들어가서 반복문이 멋대로 돌아다닌것이다.
초기 코드에서 Scanner().nextInt()를 사용해서 개행문자를 제거했었다.
2. 시간초과
상당히 곤란했던 문제이다. Kotlin에서 파이썬 문제 풀때나 보았던 시간초과라니....
알고보니 Scanner를 사용하면 시간이 오래걸리는 문제가 있다고 한다. 따라서 Scanner 대신 BufferedReader, InputStreamReader를 import 하고, readLine()으로 읽어온뒤 각자 형태에 맞게 .toInt 또는 .toString 으로 타입 변환을 해주었다.
스택 ADT에 관한건 어렵지 않았으므로 (Kotlin 문법 공부차 풀이 한 문제) 자료구조에 대한 설명은 Pass하며 공부하면서 배운 내용을 간략하게 정리해보았다.
1. Array, ArrayOfNulls
말 그대로 배열이다. 따로 Import 해줄것은 없으며, 사용법은 아래와 같다.
ArrayOfNulls는 크기를 지정해주면 해당 크기만큼 null로 초기화 되어 나오는 배열이다.
https://itandhumanities.tistory.com/2
[Kotlin] 배열 사용법 정리
Java의 배열 선언 int[] i_array; int mArray[]; 자바에서는 두가지 방법으로 배열을 선언할 수 있는데요. 타입[ ] 변수; 타입 변수[ ]; 대괄호 [ ]는 배열 변수를 선언하는 기호로 사용되는데 타입 뒤에 붙
itandhumanities.tistory.com
2. Scanner
코틀린에서는 Java의 Scanner를 그대로 사용가능한데 (정확히는 JAVA의 모듈들을 Import 해서 사용가능하다) 이때 중요한 점은 Scanner 선언시 system.in이 아니라 back-tick( ` ) 을 사용하여 in을 감싸준다.
system.`in`
3. 전역변수 선언
코틀린에서는 JAVA의 static이 없다.
JAVA에서 static이 붙은 메소드는 클래스가 메모리에 적재될 때 자동으로 생성되므로 인스턴스 생성 없이도 바로 사용이 가능하다.
코틀린에서 static을 대체한 키워드가 companion object이다.
이 외에도 많은 기능을 포함하고 있는데 아래 블로그를 참고하였다.
https://www.bsidesoft.com/8187
[kotlin] Companion Object (1) - 자바의 static과 같은 것인가? - Bsidesoft co.
개요 코틀린(Kotlin)의 Companion object는 단순히 자바(Java)의 static 키워드를 대체하기 위해서 탄생했을까요? 이 갑작스러운 질문은 코틀린에서 왜 static을 안 쓰게 되었는지 이해하는 데 큰 도움이 될
www.bsidesoft.com
4. when 문
C언어에서의 switch - case의 간략화 버전이라고 이해했다.
훨씬 간단하게 사용가능하며 코틀린을 하면서 파이썬과 C의 중간 정도 되는 문법이라는 느낌을 받았다.
사용법은 아래 코드에서 볼 수 있다.
5. !!과 ?
코틀린에서 파이썬의 어노테이션과 비슷하게 타입을 지정해줄 수 있는데 (강제성이 있는듯해보임) 이때 타입 뒤에 붙는 기호들이 !!과 ? 이다.
!!은 들어온 타입이 null이면 절대 안된다! 라는 뜻이며
?는 들어온 타입이 null이어도 상관없다! 라는 뜻이다.
아래 링크에서 참고하였다
https://cishome.tistory.com/109
[kotlin] 코틀린 자료형2
코틀린은 변수를 사용할 때 반드시 값이 할당되어 있어야 한다는 원칙이 있습니다. 값이 할당되지 않은 변수를 사용하면 오류가 발생합니다. 값이 없는 상태는 null 이라고 합니다. 코틀린은 기
cishome.tistory.com
<사용법>
fun Foo(val param1: Int?, val param2: Int!!)Int{
param1 = 10
return param1 + param2
}
풀이 코드
import java.util.*
import java.io.BufferedInputStream
import java.io.BufferedReader
import java.io.InputStreamReader
class Stack{
companion object{
var stack_pointer:Int = 0
}
fun push(stack:Array<Int?>, value:Int){
stack[stack_pointer++] = value
}
fun pop(stack:Array<Int?>): Int? {
return if(this.empty() == 1) -1 // 스택이 비어있는 경우 -1 리턴
else{
val temp: Int? = stack[stack_pointer - 1]
stack[stack_pointer--] = null
return temp
}
}
fun size():Int{
return stack_pointer
}
fun empty():Int{
return if(this.size() == 0){
1
}else{
0
}
}
fun top(stack:Array<Int?>):Int?{
return if (this.size() == 0)
-1
else{
stack[stack_pointer - 1]
}
}
}
fun main() = with(BufferedReader(InputStreamReader(System.`in`))){
val array = arrayOfNulls<Int>(10000) // stack 저장될 공간 생성
val iter = readLine().toInt() // 초기 반복문 실행
val stack = Stack()
for(i in 1 .. iter){
val op = readLine().split(' ')
when(op[0]){
"push" -> stack.push(array, op[1].toInt()) // Push 조건 실행
"pop" -> println("${stack.pop(array)}") // Pop 조건 실행
"size" -> println("${stack.size()}") // Size 조건 실행
"empty" -> println("${stack.empty()}") // Empty 조건 실행
"top" -> println("${stack.top(array)}") // Top 조건 실행
}
}
}