[Kotlin] for문을 사용할 때 느낀 고찰
1159번: 농구 경기
상근이는 농구의 세계에서 점차 영향력을 넓혀가고 있다. 처음에 그는 농구 경기를 좋아하는 사람이었다. 농구에 대한 열정은 그를 막을 수 없었고, 결국 상근이는 농구장을 청소하는 일을 시작
www.acmicpc.net
문자열을 공부하면서 부정확한 for문의 이해로 몇 번의 실패를 경험하게 됐다.
필자가 문제를 풀면서 헷갈렸던 점은
- 1.for문의 'in' 다음으로 배열 혹은 collection을 선언하는 것
- 배열 혹은 collection의 크기를 범위로 두는 것
처음에 문제를 풀 때는 첫 번째 방법으로 접근하려 했다.
import java.io.*
fun main() {
val br = BufferedReader(InputStreamReader(System.`in`))
val n = br.readLine()!!.toInt()
val cnt = IntArray(26)
var isOk = false
for(i in 0 until n) {
val name = br.readLine()
val first = name.first()
cnt[first.toInt()-97]++
}
for(j in cnt) {
if(j >= 5) {
print((cnt.indexOf(j)+97).toChar())
isOk = true
}
}
if(!isOk) println("PREDAJA")
br.close()
}
이렇게 푼 이유는 cnt의 indexOf을 활용해서 해당 값을 출력하고자 했다. 5보다 같거나 큰 값을 찾아서 cnt 배열에 해당 값의 index + 97을 하면 원하는 값이 출력되니까 말이다.
하지만 문제에 나타나는 테스트 케이스를 다 성립함에도 불구하고 틀렸다고만 나왔다.
그래서 전체적으로 cnt 배열값이 어떤 결과가 나오는지 확인해봤다.
for (j in cnt) {
print("${(cnt.indexOf(j)+97).toChar()} ")
}
결과 : a b a a a a a h a a k a a a a p a a p a a a a a a a
문제의 답은 b,k 인데 j가 5보다 큰 값이 b, k 에 있는 index이므로 언뜻 보면 그럴싸한 정답으로 보인다.
하지만 만약에 j의 값이 5개로 중복된다면, 값 또한 중복된 결과가 나올 수 있다는 것을 간파하지 못했다.
실제로 문제의 입력에서 조건을 거치면 b가 6개 나오고, k가 7개 나오므로 해당 로직을 구현했을 때 성공했다는 안일한 생각을 해버렸다.
그래서 다음과 같이 수정을 거치면서 정답을 찾게 됐다. 다음은 완성된 코드이다.
import java.io.*
fun main() {
val br = BufferedReader(InputStreamReader(System.`in`))
val n = br.readLine()!!.toInt()
val cnt = IntArray(26)
var isOk = false
for(i in 0 until n) {
val name = br.readLine()
val first = name.first()
cnt[first.toInt()-97]++
}
for(j in cnt.indices) {
if(cnt[j]>=5) {
print((j+97).toChar())
isOk = true
}
}
if(!isOk) println("PREDAJA")
br.close()
}
막상 구현하고 나니 정말 간단한 접근법이였지만 테스트 케이스만 믿고 정답을 제출했던 일차적인 실수였다.
이번 문제를 계기로 문제의 테스트 케이스에 국한하지 않고, 다양한 경우의 수를 입력해서 정답에 접근할 수 있도록 더 노력해야 겠다.