
N개의 최소공배수
주어진 배열의 모든 수의 최소공배수를 구해야한다.
배열의 요소 두 수를 가져와 최소공배수와 최대공약수를 구하고 구해진 최소공배수를 다음 수와 계산해 최대공약수와 최소공배수를 마지막 요소까지 구해준다.
예전에 최소 공배수 문제가 나왔을때 공부했던 유클리드 호제법을 이용해 풀 수 있었다.
나의풀이
class Solution {
fun solution(arr: IntArray): Int {
var answer = arr[0]
var tempGcd = 0
for ( i in 1 until arr.size){
tempGcd = gcd(answer, arr[i])
answer = lcm(answer, arr[i], tempGcd)
}
return answer
}
tailrec fun gcd(a: Int, b: Int): Int {
return if (b == 0) a else gcd(b, a % b)
}
fun lcm (a:Int, b: Int, gcd: Int) = a * b / gcd
}
다른사람의 풀이
class Solution {
fun solution(arr: IntArray): Int {
var answer = 1
while(true) {
var x = 0
for(a in arr) x += answer%a
if(x==0) return answer
answer++
}
return answer
}
}
to자료형() 메소드를 활용할 수 있음업캐스팅: 자식클래스 -> 부모클래스
var birds = mutableListOf<Bird>() birds.add(Sparrow(name) as Bird)Sparrow는 Bird의 자식클래스라 Bird로 형변환해 리스트에 넣을 수 있다.
as Bird부분은 생략이 가능하다.
다운캐스팅: 부모클래스 -> 자식클래스
var s1:Sparrow = birds.get(0)Sparrow는 Bird가 가져야할 정보를 모두 가지고 있지 않으면 오류가 난다.
is로 자료형의 타입을 확인할 수 있다. if(name is String) {
println("name은 String 타입입니다")
} else {
println("name은 String 타입이 아닙니다")
}
Pair를 사용해 두 개의 인스턴스 리턴 var chicken = Chicken()
var eggs = chicken.getEggs()
var listEggs = eggs.toList()
// first, second로 관리
var firstEgg = eggs.first
var secondEgg = eggs.second
// 리스트로 관리
var firstEgg = listEggs[0]
var secondEgg = listEggs[1]
}
class Chicken {
fun getEggs(): Pair<String, String> {
var eggs = Pair("달걀", "맥반석")
return eggs
}
}
Triple을 사용해 세 개의 인스턴스 리턴fun main() {
var chicken = Chicken()
var eggs = chicken.getThreeEggs()
var listEggs = eggs.toList()
// first, second, third로 관리
var firstEgg = eggs.first
var secondEgg = eggs.second
var eggTime = eggs.third
// 리스트로 관리
var firstEgg = listEggs[0]
var secondEgg = listEggs[1]
var eggTime = listEggs[2]
}
class Chicken {
fun getThreeEggs(): Triple<String, String, Int> {
var eggs = Triple("달걀", "맥반석", 20230101)
return eggs
}
}
var strNum = "10"
var result = strNum?.let { // 중괄호 안에서는 it으로 활용함 Integer.parseInt(it) } println(result!!+1)
var alphabets = "abcd"
with(alphabets) {
// var result = this.subSequence(0,2)
var result = subSequence(0,2)
println(result)
}
var result = student?.also { it.age = 50 }
var result = student?.apply { student.age = 50 }
객체에서 호출하지 않을 때
var totalPrice = run { var computer = 10000 var mouse = 5000 computer+mouse } println("총 가격은 ${totalPrice}입니다")
객체에서 호출할 때 : with와 달리 null체크를 할 수 있어 안전하게 사용가능
student?.run { displayInfo() }
Scope에서 접근방식 this | Scope에서 접근방식 it | |
|---|---|---|
| 블록 수행 결과를 반환 | run, with | let |
| 객체 자신을 반환 | apply | also |
- 하위클래스에서 오버라이드 할수없음
- public멤버에만 접근할 수 있음
fun String.isEmailValid(): Boolean {
val pattern = "[a-zA-Z0-9._-]+@[a-z]+\\.+[a-z]+"
return matches(pattern.toRegex())
}
동기적 프로그래밍이라고 함비동기 프로그래밍은 요청을 보내고 결과값을 받을 때까지 다른 작업을 수행하기 때문에 여러일을 한번에 수행fun main())가 존재프로세스와 쓰레드
프로그램을 실행해 메모리에 올라가면 이를프로세스라고 한다.
프로세스 안에 작업단위를 쓰레드라고 한다.
쓰레드는 각 독립된 메모리영역인 Stack을 가짐
Kotlin/kotlinx.coroutines: Library support for Kotlin coroutines (github.com)
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0-RC")
}
fun main() {
thread(start = true) {
for(i in 1..10) {
println("Thread1: 현재 숫자는 ${i}")
runBlocking {
launch {
delay(1000)
}
}
}
}
thread(start = true) {
for(i in 50..60) {
println("Thread2: 현재 숫자는 ${i}")
runBlocking {
launch {
delay(1000)
}
}
}
}
}
쓰레드를 동시에 시작해서 먼저 실행된 쓰레드의 숫자가 먼저 나오게됨
launch async 를 많이 사용launch는 결과값이 없는 코루틴 빌더이고 Job객체로 코루틴을 관리Dispatcher로 지정 (Dispatcher간 변환이 필요한 경우 withContext를 사용)GlobalScope: 앱이 실행된 이유에 계속 수행되어야 할 때
CoroutineScope: 필요할때 생성 후 정리가 필요
Dispatchers.Main: UI와 상호작용하기 위한 메인쓰레드
Dispatchers.IO: 네트워크나 디스크 I/O작업에 최적화되어있는 쓰레드
Dispatchers.Default: 기본적으로 CPU최적화되어있는 쓰레드
블로킹 (Blocking)
Thread A가Thread B결과를 기다릴때Thread A는 Blocking상태이고Thread B의 결과가 나올때까지 해당 자원을 사용하지 못함
Suspend(Non-Blocking)
Thread A가 Object1을 실행하다가 Object2의 결과를 기다릴 때 Object1은 suspend로 바뀌고Thread A는 멈추지 않고 다른작업을 수행하다가 Object1이 결과를 다시 받으면Thread A가 다시 Object1을 수행한다.