본문 바로가기

[TIL][내일배움캠프]

[내일배움캠프][TIL] 23.11.21 (화) - 두 개 뽑아서 더하기, it

1. 코드카타

 

오늘 내가 푼 알고리즘 문제는 '두 개 뽑아서 더하기' 이다.

 

 두 개 뽑아서 더하기
 정수 배열 numbers가 주어질 때, numbers에서 서로 다른 인덱스에 있는 두 개의 수를 뽑아 더해서 만들 수 있는 모든 수를 배열에 오름차순으로 담아 return하도록 solution 함수를 완성하기.
 ex) numbers = [2, 1, 3, 4, 1]  ->  result = [2, 3, 4, 5, 6, 7]
       numbers = [5, 0, 2, 7]      ->  result = [2, 5, 7, 9, 12]

 

우선은 '서로 다른 인덱스에 있는 두 개의 수를 뽑아서 더하는' 코드부터 짜기로 하자.

 

for (i in 0 until numbers.size){
            for (j in i+1 until numbers.size){
                answer += numbers[i]+numbers[j]
            }
        }

 

여기서 j는 i와 같은 값이 나오면 안 되기 때문에 (아니면 '서로 다른'이라는 조건에 위배된다)

무조건 i보다는 1 큰 값을 넣어야 모든 경우의 수를 다 구할 수 있게 된다.

 

그러니까 위 코드대로 하게 되면 다음과 같이 반복된다.

 

i = 0 -> j = 1, 2, 3, 4, … , n-1 (여기서 n은 numbers의 인덱스 개수)
i = 1 -> j = 2, 3, 4, … , n-1

i = n-2 -> j = n-1

 

 

자, 이제 값은 다 구했으니 정렬하는 일만 남았다.

 

       return answer.sorted().toIntArray()

 

sorted() : 데이터 변경이 가능한 배열, 리스트의 요소들을 정렬하는 함수. 뒤에 특별한 단어를 추가하지 않는 이상 보통은 오름차순으로 정렬시킴.

toIntArray() : answer의 값을 IntArray형으로 변환 (이걸 빼니까 에러가 떠서 삽입했다.)

 

그리고 내가 짠 코드가 맞는지 확인하기 위해서 테스트 케이스를 돌려본 결과.

 

 

어라?

값 자체는 정확하게 나오는데 중복값이 같이 출력된다.

 

그렇다. 이 문제에서 가장 중요한 점은 '중복값을 어떻게 제거하는가?' 였다.

위의 계산식은 서로 다른 두 인덱스 간의 모든 경우의 수를 다 구할 수 있지만, 당연히 그 경우의 수 중에서는 서로 중복된 값이 있고, 나는 중복값을 제거하는 코드를 넣지 않아서 이런 식으로 중복값 또한 같이 출력되었다.

 

 

그렇다면 어떻게 해야 중복값을 제거할 수 있을까?

if 절을 삽입해서 중복값을 제거할 수 있는 코드를 만들까?

아니면 중복값을 제거하는 함수가 있지 않을까?

 

둘 중 어느 쪽으로 할지 고민하다가 추후에 이런 함수들을 써야할 일이 생기지 않을까 싶어서 이참에 함수를 찾아보기로 했다.

 

그리하여 함수를 찾아본 결과, 다음과 같은 함수를 발견하였다.

 

 distinct() : 중복된 값을 제거하는 함수

 

그리고 이것을 return 값에 넣어보았다.

 

        return answer.distinct().sorted().toIntArray()

 

이걸로 다시 테스트 케이스를 돌려보니 깔끔하게 통과가 되었다.

 

 

그리하여 완성된 최종 코드는 다음과 같다.

 

class Solution {
    fun solution(numbers: IntArray): IntArray {
        var answer: IntArray = intArrayOf()
        
        for (i in 0 until numbers.size){
            for (j in i+1 until numbers.size){
                answer += numbers[i]+numbers[j]
            }
        }
        
        return answer.distinct().sorted().toIntArray()
    }
}

 

오늘도 Kotlin 문법에 한 발자국 다가간 하루였다.

 

 

2. it

 

Kotlin을 공부하면서 본 단어 중에 나에게는 가장 생소한 단어가 하나 있었는데 바로 'it'이었다.

 

종종 코드카타를 통해 알고리즘 문제를 푼 다음에 시야를 넓히기 위해서 다른 사람들이 짠 코드들도 참고하는 시간을 갖는데 그 때 보이던 것들 중에 it이 있었다.

 

보다보니 이게 어떤 용도로 사용하는지 까지는 알게 됐는데 이걸 막상 내가 쓰려고 하니 어떻게 써야하는지 모르겠더라.

 

그래서 오늘은 이 it에 대해서 자세히 알아가기로 했다.

 

'it'이란?

'it'은 Kotlin에서 람다 표현식에서 사용되는 특별한 식별자(identifier)이다.

그런데 여기서 또 한 가지 궁금증이 생긴다.

 

그러면 람다 표현식은 또 뭐야?

 

람다 표현식(lambda expression)이란 간결하게 함수를 선언하고 전달하는 방법을 제공하는 함수형 프로그래밍 언어의 특징 중 하나를 말한다.

쉽게 말해서 간결한 함수식을 뜻하는 건데 예시를 들어보자.

 

다음은 두 변수에 대한 덧셈을 나타내는 함수이다.

 

fun main(){
    fun fn(a:Int, b:Int):Int {return a+b}
    println(fn(1,2))
}

 

이를 람다 표현식으로 나타내면

 

fun main(){
    val fn = {a:Int, b:Int -> a+b}
    println(fn(1,2))
}

 

위의 식보다 훨씬 깔끔하고도 간결하게 나타낼 수 있다.

 

 

요약하자면, it은 간결하게 함수식을 나타낼 수 있는 람다식에서 사용할 수 있는 매개변수이다.

 

it을 쓰는 방법

 

그렇다면 it은 어떻게 쓰는 걸까?

 

it은 매개변수가 하나일 때 사용할 수 있다.

 

예를 들어보자.

 

val numbers = listOf(1, 2, 3, 4, 5)

val squaredNumbers = numbers.map { it * it }

println(squaredNumbers)

 

다음과 같이 리스트 numbers가 주어질 때, 각 요소의 제곱을 요소로 가지는 리스트를 구하는 코드를 구하고자 한다.

이 때, it을 사용하여 간단하게 구현할 수 있다.

 

본래라면 for문을 사용하거나 변수를 따로 지정해야 하지만, it을 사용하면 변수를 따로 지정할 필요가 없어진다.

 

단, 매개변수가 둘 이상일 때에는 it을 사용할 수 없고 반드시 매개변수를 선언해야 한다.