오늘은 배열에 관련된 문제를 풀다가 새로 알게 된 것이 많았다. 그것에 대해서 정리해보려고 한다
1. 내가 푼 문제
프로그래머스에 있는 'x만큼 간격이 있는 n개의 숫자' 라는 간단한 문제이다
- 문제
함수 solution은 정수 x와 자연수 n을 입력 받아, x부터 시작해 x씩 증가하는 숫자를 n개 지니는 리스트를 리턴해야합니다. 다음 제한 조건을 보고, 조건을 만족하는 함수, solution을 완성해주세요.
<제한 조건>
x는 -10000000 이상, 10000000 이하인 정수입니다
n은 1000 이하인 자연수입니다
<입출력 예>
x | n | answer |
2 | 5 | [2,4,6,8,10] |
4 | 3 | [4,8,12] |
-4 | 2 | [-4,-8] |
풀이 과정은 매우 간단하기 때문에 많이 적지 않으려고 한다. 나는 n개의 값을 가지는 빈 배열을 생성한뒤 그 곳에 하나하나 값을 입력하는 방식으로 코드를 작성했다.
그리고 문제를 여럿 풀다가 알게된 중요한 것 중 하나는 문제의 조건을 꼭 잘 확인해보는 것이다. 이 문제의 경우 x의 최대값은 천만, n의 최대값이 1000이기 때문에 100억이라는 숫자까지 출력될 수 있다. 따라서 출력값이 약 21억 정도가 최대값인 Int의 범위를 넘어서기 때문에 Long 형식으로 출력해야 한다.
class Solution {
fun solution(x: Int, n: Int): LongArray {
var answer = LongArray(n)
for (i in 1..n){
answer[i-1] = x.toLong() * i.toLong()
}
return answer
}
}
인덱싱으로 빈 배열에 값을 하나 하나 넣어주었고, Int로 받은 변수들은 Long으로 형변환을 한 뒤 계산하였다. 위와 같이 코드를 작성해서 제출 하였고 답으로 통과가 되었다.
지금 다시 코드를 보며 생각해보니 x와 i모두 Long으로 변환할 필요 없이 둘 중 하나만 변환을 해도 된다는 생각이 들었다. Int와 Long을 곱하면 당연히 Long으로 출력되기 때문이다.
문제를 풀고나서 다른 사람들이 작성한 답안을 보니 내가 몰랐던 다양한 방법들이 있다는 것을 알게되었고, 새로 알게된 부분들에 대해 정리해 보려고한다.
2. Kotlin에서의 배열에 대해 새로 알게된 것들
2-1. 배열에 값을 추가하기(?)
배열은 크기가 고정되어 있기 때문에 배열 안에 있는 값을 변경할 수는 있지만 요소를 추가하는 것은 불가능하다. 그렇기 때문에 내가 문제를 풀때도 크기를 지정한 빈 배열에 값을 채워넣는 방식으로 문제를 풀었다. 그런데 다른 사람들의 풀이를 보니 아무것도 없는 배열에 요소를 추가하여 문제를 푼 것처럼 보이는 답안이 있었다.
class Solution {
fun solution(x: Int, n: Int): LongArray {
var answer = longArrayOf()
for(i in 1..n) {
answer += x.toLong() * i
}
return answer
}
}
answer라는 크기도 없고 요소도 없는 빈 배열을 만든 뒤 거기에 값을 하나하나 더하는 형태로 답안을 완성했다. 내가 알기로는 이런 것은 불가능한데 이상하다라고 생각했다.
fun main() {
val array1 = intArrayOf(1,2,3,4,5,6)
array1.plus(7)
println(array1.contentToString())
val array2 = array1.plus(7)
println(array2.contentToString())
}
코드 실행 결과
[1, 2, 3, 4, 5, 6]
[1, 2, 3, 4, 5, 6, 7]
위와같이 plus 함수를 이용하여 요소를 추가한 배열을 '새로' 만들 수는 있다. array1.plus(7)의 코드를 실행해보았자 array1은 변하지 않고 그대로 있다. 새로 선언한 변수에 요소를 추가한 배열을 넣는 것은 가능하지만 원래 배열의 크기를 바꿀 수는 없다.
다시 답안으로 돌아가 생각해보니 언뜻보기에는 배열에 요소를 추가한 것 처럼 보이지만 +=을 이용해 기존에 선언했던 변수에 요소를 추가하여 새로 만든 배열을 집어넣는 형태인 것을 알 수 있었다. 요소를 추가할 때마다 새로운 배열을 계속 만드는 형태로 되어있는 것이다. 배열에 요소를 추가하는 것처럼 보이니 간단하고 이해하기도 쉽다는 생각이 들기도 하였지만 배열을 계속 새로 만드는 것이니 비효율적인 것일지도 모르겠다는 생각이 들었다.
2-2. 람다식을 통해 배열 만들기
답안 중에는 함수 식이 단 한줄에 불과한 것도 있어 다소 놀랍기도 했다.
class Solution {
fun solution(x: Int, n: Int): LongArray = LongArray(n) {x.toLong() * (it + 1)}
}
너무 간단하고 명료한 것 처럼 보이지만 생략 가능한 것들을 모두 생략한 식이기 때문에 이해하려면 알아야 할게 많은 것 같아 차근차근 정리해보았다.
- 함수 간단하게 작성하기
fun triple(x:Int): Int {
return x*3
}
Kotlin에서는 위와 같이 표현식이 한 줄인 간단한 함수는 중괄호와 return을 생략하고 =을 이용해 한 줄로 표현이 가능하다.
fun triple(x: Int): Int = x * 3
이 함수는 위와 완전히 동일하다. 그리고 타입 추론이 가능한 경우면 출력 값의 타입 역시 생략할 수 있다.
fun triple(x: Int) = x * 3
위와 같이 정말 짧고 깔끔하게 함수를 작성할 수 있다
- 배열을 간단하게 만들기
배열은 Array(개수,{식})과 같은 형태로 간단하게 생성할 수 있다
fun main() {
val array1 = Array(5, {a -> a*2})
println(array1.contentToString())
}
코드 실행 결과
[0, 2, 4, 6, 8]
위와 같이 작성된 코드에서 a에는 인덱스에 해당하는 값이 들어가게 되고 람다식에 따라 0,1,2,3,4에 2를 곱한 값이 배열로 출력되게 된다.
함수에서 맨 오른쪽에 있는 람다식은 소괄호 밖으로 빠져나오게 작성하는 것도 가능하다. Intellij내에서도 위와 같이 코드를 작성하면 노란색 느낌표가 뜨는데 둘다 사용가능하지만 람다식은 소괄호 밖으로 작성하는 것을 권하는 것 같다.
val array1 = Array(5, {a -> a*2})
val array1 = Array(5) {a -> a*2}
둘의 결과는 완전히 동일하다. 또한 중괄호에 람다식 대신에 it을 이용하여 더 간단하게 만들 수도 있다
val array1 = Array(5, {a -> a*2})
val array1 = Array(5) {a -> a*2}
val array1 = Array(5) {it*2}
위의 식에서 it에는 인덱스의 값이 들어가게 되고 세 코드 모두 동일한 결과를 출력한다
- 간단하게 작성된 함수 다시 살펴보기
class Solution {
fun solution(x: Int, n: Int): LongArray = LongArray(n) {x.toLong() * (it + 1)}
}
이제 위 식을 다시 보면 모든 것이 이해가 간다. 함수의 리턴값으로는 LongArray가 나오게 되고 LongArray는 n개의 요소를 가지고 있으며 그 요소의 값은 x와 인덱스에 1을 더한 값(인덱스는 0부터 시작하기 때문에 1,2,3,4,5..... 으로 계산하려면 1을 더해주어야 한다)을 곱한 값이 된다.
그런데 위의 식도 자세히 보니 리턴값의 타입이 LongArray라는 것을 굳이 지정해주지 않아도 리턴값이 LongArray라는 것을 추론할 수 있기 때문에 생략이 가능하다
class Solution {
fun solution(x: Int, n: Int) = LongArray(n) {x.toLong() * (it + 1)}
}
따라서 위와 같이 조금 더 간단하게 표현할 수 있다. 코드 역시 문제없이 잘 작동한다.
3. 오늘 알게 된 것
- Kotlin에서 함수를 간단하게 표현하는 것에 대해 조금 더 잘 알게 되었다.
- 람다식을 이용해 간단하게 배열을 생성할 수 있다는 것을 알게 되었다.
- 위와 같은 식들에 익숙해지기 위해 조금 더 연습이 필요할 것 같다.
'오늘 배운 것' 카테고리의 다른 글
2024-03-18 오늘 배운 것 (2) | 2024.03.18 |
---|---|
2024-03-17 Kotlin 배열을 문자열로 출력하기 (2) | 2024.03.17 |
24-03-16 Kotlin 이중 반복문 빠져나가기 (2) | 2024.03.16 |
2024-03-14 Kotlin 숫자(Char) Int로 변환하기 (2) | 2024.03.14 |
2024-03-13 오늘 배운 것 (2) | 2024.03.13 |