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을 수행한다.