Kotlin 사전캠프 TIL 13일차

노재원·2024년 4월 4일
0

내일배움캠프

목록 보기
13/90

동기, 비동기 전체 발표하기

실무할 때는 제대로 다루지도 못하던 비동기를 내 손으로 다루게 되다니!
다행인 점은 chatGPT의 도움과 최신화 된 레퍼런스들 덕분에 마침내 이해에 성공해서 발표 자체는 수월하게 끝난 것 같다. 물론 개념까지만 이해한 것이기 때문에 여전히 코드로 작성하라고 하면 엉망이긴 할 것 같다.

그리고 TIL의 작성 방식도 좀 생각을 해봤는데 본 캠프에 가면 지금처럼 짤짤이 공부가 아닌 프로젝트 단위로 아득바득 뭔가 해결할 것이기 때문에 본 캠프부터 해결을 중점으로 구성을 바꾸게 될 것 같다.


문자열 다루기 기본

문자열 s의 길이가 4 혹은 6이고, 숫자로만 구성돼있는지 확인해주는 함수, solution을 완성하세요. 예를 들어 s가 "a234"이면 False를 리턴하고 "1234"라면 True를 리턴하면 됩니다.

문제 링크

fun solution(s: String): Boolean = s.matches("\\d{4}|\\d{6}".toRegex())

조건문을 내세우지 않고 정규표현식으로 표현을 해봤다. 어차피 앞으로도 다룰 일 많아질테니 마침 문제 이름도 문자열 다루기 기본 이고 복잡한 길로 돌아가려고 고른 방법이긴 하다.

\\d{4}|\\d{6} or를 담당하는 | 와 함께 \d{4}번 반복하는지 {6}번 반복하는지 체크하는 정규표현식이고 제출은 큰 문제없이 성공했다.

복잡한 정규표현식은 읽기만 해도 눈 앞이 어지럽지만 기본적인 사용법 정도는 알고 있었는데 정리할 내용이 부족하니 이 문제에 맞춰서 최대한 더 쥐어짜내봤다.


예로 아래 패턴은 같은 결과를 캡쳐해낸다.

s.matches("[0-9]{4}|[0-9]{6}".toRegex())
s.matches("\\d{4}(?:\\d{2})?".toRegex())

[0-9]\d와 동일한 범위를 지니기에 같은 결과를 가진다.
?: 는 비캡쳐 그룹으로 패턴으로는 사용할 수 있지만 캡쳐하진 않기 때문에 결과적으로 4자 또는 6자인 숫자만 찾아낸다.
예시로 s가 123456일 경우 패턴을 매칭하면 123456 과 1234만 캡쳐되며 비캡쳐 그룹에 포함된 56은 캡쳐되지 않는다.

?는 그렇다 쳐도 ?: 패턴을 이해하느라 시간이 꽤 걸렸는데 예제를 수없이 돌려보고 chatGPT와 함께 머리를 쥐어짜내서 해석에 성공했다. 아무래도 핵심은 캡쳐 아니겠는가?

물론 완벽한 정규표현식은 아니겠지만 표현할 줄 아는가에 대해서는 계속 공부를 해야겠다.

\D는 아라비안 숫자가 아닌 나머지를 가리킨다. 대문자로 바뀌면 패턴이 정반대가 된다. 예로 \s 는 space 공백을 찾는 패턴인데 \S는 space 공백을 제외한 나머지를 찾는다.


그리고 내가 풀어낸 방식은 사실 문제가 간단한데 괜히 정규표현식을 들먹여서 바람직한 정답은 아니라고 생각한다.

역시나 다른 분들의 풀이는 훨씬 정직하고 간결했다.

(s.length == 4 || s.length == 6) && s.toIntOrNull() != null

s.all { it.isDigit() } && ((s.length == 4) || (s.length == 6))

다른 분들의 풀이인데 골치 안아프게 이렇게 isDigit 이나 intOrNull 을 끌어다 쓰면 편한 건 아는데 이번엔 굳이? 아득바득 정규표현식 써보겠다고 난리친 결과물이긴 하다.

그리고 정규표현식을 사용하면 컴파일, 실행 과정에서 오버헤드가 추가로 발생할 수 있어 최적화된 함수가 존재한다면 이러한 함수를 사용하는 것이 성능 향상에 도움이 될 것이다.

0개의 댓글