코틀린으로 조건문 반복문 다뤄보기

김태영·2024년 5월 3일
0

TIL

목록 보기
3/70
post-thumbnail

오늘도 역시나 알고리즘 문제를 풀어보았다. 술술 풀린 문제가 있어서 어쩌면 조금 코틀린과 친해진걸지도 모른다는 생각이 드는 하루였다. 문제가 쉬운 게 절대 아닐.. 아니여야.. 아니였으면.. 좋겠다.

삼항 연산자가 없는 코틀린

사실 나는.. 삼항 연산자 중독이다. if 어쩌구.. else 어쩌구.. 를 작성하기에 내 타자 속도는 너무 느리기 때문이다! 라는 이유는 아니고 짧게 작성하는 걸 선호하기 때문이다. 숏폼이 유행하는데에는 짧은 걸 선호하는 사람들이 많다는 증거가 아닐까? 그렇지만 염두해둘것은, 알고리즘은 가독성과 성능이 중요하다는 것이다. 아무튼 문제로 돌아와서 코틀린 이 자식 삼항 연산자가 없댄다. 그 대신 if와 else가 표현식이라서 특정 값을 반환한다.

if (조건) 조건이 참일 때 반환 값 else 조건이 거짓일 때 반환 값

// else if도 가능하다!
if (조건) a else if (조건) b else c

비트 연산으로 홀수 짝수 구분하기

& 비트 연산으로 짝수인지 홀수인지 판별할 수 있다는 사실을 새롭게 알게되었다. & 비트 연산은 양쪽의 비트가 모두 참일때만 1, 그 외의 경우엔 0으로 계산된다. 자, 그럼 이걸 어떻게 활용해서 판별하는 것일까.

  • 홀수와 짝수는 1의 자릿수만으로 구분할 수 있다.
    • 1은 2진수로 0001이다.
    • 홀수를 2진수로 나타내면 …1 이고, 짝수는 …0 이다.
    • 즉, 2진수로 나타낸 수와 1을 & 연산 했을 때, 0이 나온다면 짝수이고 1이 나온다면 홀수이다.

그렇다면 이제 홀짝을 구분할 때 2로 나눈 나머지를 이용하는 방법 말고도 비트 연산을 사용해 구분할 수 있겠다! 사실 비트 연산자는 코틀린에서 잘 사용되지 않는다고 하는데, 모르고 있는 것과 알고 있는 것의 차이는 크니까 잠깐 알아보았다.

if (num and 1 == 0) "짝수" else "홀수"
if (num.and(1) == 0) "짝수" else "홀수"

누적 합 구하기

“누산기”라는 말을 들어본 적이 있나. 물론 sum을 사용해 총합을 구할 수 있겠지만, 컬렉션 요소 그대로만 더할 수 있다는 아쉬움이 있다. 그래서 알아보았다 >코틀린의 누산기!<

코틀린에는 reducefold라는 컬렉션 요소들의 누적 합을 구해주는 함수가 있다고 한다. 둘은 비슷한 역할을 하지만, 초기값을 줄 수 있는지의 여부에서 차이점이 있다.

reduce

reduce컬렉션의 첫 번째 요소를 초기값으로 사용한다. 따라서 첫 요소가 빈 값이라면 예외가 발생한다! 그럴땐 reduceOrNull을 사용한다고 한다. 추가로, reduce는 첫 요소에는 계산을 적용하지 않기 때문에 값을 변경해서 누적하고 싶을 때는 약간의 주의가 필요하다.

numbers.reduce { total, num -> total + num }

fold

fold초기값을 지정해줄 수 있다.

numbers.fold(0) { total, num -> total + num }

String과 Char

상황은 자릿수 더하기 문제를 풀면서 시작한다. 10으로 반복해서 나눈 나머지를 합하면 풀 수 있겠지만, 문자열로 변환해 각 문자열에 해당하는 숫자를 더하는 방식으로 풀고 싶었다. 그래서 자료형에 대한 생각을 1도 하지 않고 코드를 싸질렀다 작성해보았다.

fun solution(n: Int): Int {
	var answer = 0

	for (s in n.toString()) {
        answer += s.toInt()
	}
		
    return answer
}

결과는 당연히 대 실 패다. 로그를 확인해보니 s가 Char 형이라 toInt()를 사용하면 해당 문자의 아스키코드를 반환하는 것 같았다. 해결하기 위한 방법을 다음과 같이 몇 가지 생각해보았다.

  • String 형으로 변환 후 Int 형으로 다시 변환해서 합하자!

    for (s in answer.toString()) {
    		answer += s.toString().toInt()
    		// 형 변환이 너무 잦게 일어나는 것 같다..
    }
  • 주어진 숫자를 아예 String 배열로 만들어버리자!

    for (s in n.toString().split("")) {
    		if (s != "") answer += s.toInt()
    		// 빈 값인지 추가로 확인해줘야 해서 불편하다.
    }

    “문자열” 을 정의할 때는 꼭 큰 따옴표를 사용하는 것을 잊지말자.
    작은 따옴표를 사용했다가 오류가 발생해서 굉장히 당황했었다.. 나는 멍청이..

문제를 풀긴했지만 다른 방법은 없을까 생각하던 중에 만나고 말았다. digitToInt() 라는 녀석을..!

digitToInt

그래 생각해보면 String 형을 Int 형으로 바꾸는 함수가 있는데 Char 형을 Int 형으로 바꾸는 함수가 왜 없겠는가. digitToInt는 정확하게는 문자가 나타내는 10진수 숫자 값을 반환해주는 함수이다.

for (s in n.toString()) {
	answer += s.digitToInt()
}

앞으로 자료형을 잘 생각하면서 풀이하는 습관을 들여야겠다. 특히 큰 따옴표 작은 따옴표는 정말 엄청난 충격이었다. 나는 작은 따옴표가 취향인데 말이다.

profile
화이팅

0개의 댓글