코틀린의 기초 문법 살펴보기

김태영·2024년 5월 2일
0

TIL

목록 보기
2/70
post-thumbnail

오늘은 알고리즘 문제와 함께 코틀린의 기초 문법에 대해 살펴보았다.

코틀린의 나눗셈

첫 문제는 num1을 num2로 나눈 값에 1,000을 곱한 후 정수 부분을 반환하는 함수를 작성해야했다.

처음엔 단순히 문제에 나온 순서 그대로 num1 / num2 * 1000으로 제출했었는데, 코틀린은 정수를 정수로 나누게 될 경우 소수점을 버린 정수로 계산이 되어 오답이라는 것이다. 그래서 이후에는 형변환을 사용해 다음과 같은 답을 제출했다.

fun solution(num1: Int, num2: Int): Int {
    var answer = num1 / num2.toDouble() * 1000 // 실수로 형변환
    return answer.toInt() // 정수로 형변환
}

정답이었지만 뭔가… 코드가 길어지니까 마음에 들지 않았다. 더 좋은 방법이 없나 싶었는데, 다른 사람의 풀이 중 단순히 계산 순서를 바꿔 num1 * 1000 / num2로 계산하신 분이 있었다. 이걸 보고 정말 세상에 똑똑한 사람은 많고 나는 더 많이 정진해야겠다는 생각이 들었다.

코틀린의 조건문

다음으로는 주어진 각이 어떤 각인지 1~4의 숫자로 리턴하면되는 문제여서, 조건문을 이용해 풀이했다.

fun solution(angle: Int): Int {
    if (angle < 90) return 1
    else if (angle == 90) return 2
    else if (angle < 180) return 3
    else return 4
}

비교연산자를 통해 조건을 작성했는데, inuntil, ..을 사용한 풀이가 대부분이었다. 모르는 게 나왔다면 알아봐야지. 이게 대체 뭐길래 다들 쓰는걸까.

범위 표현식

num in 1 until 90
num in 1..89

위의 두 문장은 같은 범위(1 ~ 89)를 표현한다. 차이점을 정리하자면 다음과 같다.

  • until : 마지막 값 포함 X
  • .. : 마지막 값 포함 O

혹시 다른 범위 표현식은 없을까?

코틀린과 아직 잘 아는 사이가 아니라 하나부터 열까지 꼭꼭 씹어 물어보는 중이다. stepdownTo라는 아이들도 있는 모양이다. step의 경우 수열의 증가 혹은 감소 폭을 지정해준다고 한다.

num in 1..10 step 3
// 1 부터 10까지 3씩 증가한다. 1, 4, 7, 10
num in 10 downTo 1
// 10 부터 1까지 1씩 감소한다. (..과 방향만 다르다)
num in 10 downTo 1 step 3
// 10 부터 1까지 3씩 감소한다. 10, 7, 4, 1

알게되었다면 적용해보는 것이 인 지 상 정. 배운 것을 이용해 다시 한 번 풀어보자.

fun solution(angle: Int): Int {
    if (angle in 1..89) return 1
    if (angle == 90) return 2
    if (angle in 91 until 180) return 3
    else return 4
}

앗 그런데 if else 말고 다른 방법은 없는 걸까? switch case 문 같은걸 사용하면 더 간단해질 것 같은데..라는 생각에 코틀린의 switch case 문을 찾아보았다.

when

코틀린에는 switch case 문의 역할을 하는 when 구문이 있다고 한다. 사용법을 간단하게 살펴보자면,

when (변수) {-> 코드
	값 -> 코드
	...
	else -> 코드
}

가 되겠다. 화살표를 사용하는 게 인상깊었다. 게다가 상수만을 조건으로 줄 수 있는 switch case 문과 다르게 “값” 부분에 “조건식”도 들어갈 수 있다고 한다! 아주 기똥찬 자식이다. 자, 이제 다시 적용해보자.

fun solution(angle: Int): Int {
    when (angle) {
	    in 1..89 -> return 1
	    90 -> return 2
	    in 91 until 180 -> return 3
	    else -> return 4
    }
}

조건식으로 ..과 until을 사용할 때 in도 같이 써주는 걸 잊지 말자.. 빼먹었다가 에러를 마주하게 될 수 있다. (경험담 아님)

등차수열의 합

이번에는 1부터 n까지의 숫자 중 짝수만 더하면 되는 문제였다. 수학 공식을 이용하면 수식 한 줄로 가능한 문제라는 생각이 들어 다음과 같이 풀이했다.

fun solution(n: Int): Int {
    var num = n / 2
    return num * (1 + num)
}

이용한 공식은 다음과 같다.

  • 1~n 까지 짝수의 합: (n/2) * (1 + n/2)
  • 1~n 까지 홀수의 합: (n/2) * (n/2)

그러다 문득 든 생각은, 어라 코틀린을 알아가려고 알고리즘 문제를 푸는건데 수학 문제 풀듯이 풀이하는게 맞나? 였다. 문제의 원래 의도는 (아마) 반복문과 조건문에 좀 더 익숙해지라고 낸 듯 싶었다. 그래서! 의도대로 코틀린의 반목문을 알아보았다.

코틀린의 반복문

보통 반복을 할 때, for 문과 while 문을 많이 사용한다. 나 같은 경우는 특정 횟수만큼의 반복에는 for 문을, 특정 조건에서만 반복에는 while 문을 사용하는 편이다.

for

for (i: Int in 1..10) {
	...
}

in 뒤에 범위 표현식 말고도 배열이나 컬렉션을 사용할 수 있다고 한다. 배열을 돌 때 자주 사용될 것 같은 녀석이다.

while

while (i > 0) {
	...
}

do {
	...
} while (i > 0)

while 문은 한 번도 실행되지 않을 수 있지만, do while 문은 최소 한 번의 실행을 보장한다. 내가 까먹을까봐 적어놓겠다. 다행히 while 문은 다른 언어들과 비슷한 것 같다.

이제 다시 문제로 돌아와서, 반복문과 조건문을 사용해 풀이해보자!

fun solution(n: Int): Int {
	var answer: Int = 0
    for (i: Int in 1..n) {
    	if (i % 2 == 0) answer += i
    }
    return answer
}

여기서 우리는 또 한 번 의문을 가지게 된다. (아님 말고..) 아 짝수만 골라내서 sum() 함수를 사용하면 될 텐데.. 코틀린에는 map이나 filter 같은 게 없는걸까?

filter

역시 있었다. filter는 조건에 맞는 원소만을 필터링해준다. 사용은 다음과 같이 한다고 한다.

(컬렉션 또는 배열).filter { 조건 }

이걸 풀이에 적용해보면,

(1..n).filter { num -> num % 2 == 0 }.sum()
// 1..10 은 1부터 10까지의 범위를 생성해준다. [1, 2, ..., n]
// filter 를 통해 짝수만 필터링한다. [2, 4, ..., n]
// sum 으로 필터링 된 범위 전부를 합한다.
// num -> 은 it 표기법을 사용해 생략이 가능하다.
(1..n).filter { it % 2 == 0 }.sum()

주석 중에 it 표기법에 대해 추가적으로 설명하자면, 람다식 내부에서 사용되는 암시적 변수로 인자가 하나인 경우에 it 키워드를 사용해 참조할 수 있다. 람다식은 나중에 더 알아보도록 하자. 아직 다루기엔 너무 이른 것 같다.

배열의 평균값

아주 약간의 (사실 많이..) 배신감을 느꼈던 문제가 있다. 정수 배열의 평균을 구하는 문제였는데, 당연히 배열을 전부 더해 배열의 길이로 나누는 방식으로 풀이를 했었다. 풀고나서 다음과 같은 코드를 봤을 때 나의 무지함에 서운함과 통탄스러움을 감출 수 없었다.

average

numbers.average()

참고로 나의 풀이는 다음과 같았다.

numbers.sum()*1.0/numbers.size
// 1.0(Double형)을 곱해 형변환을 해주었다.

average.. 오늘이라도 안 것에 기뻐하는 중이다. 다음엔 꼭 잊지않고 써먹는 날이 올 것이다.

profile
화이팅

0개의 댓글