티스토리 뷰
코드카타
프로세스
문제
프로세스의 우선순위에 따라 프로세스를 실행시키고
location번째 프로세스가 몇번째로 실행되는지를 반환하는 문제이다.
해당 문제는 큐(queue)를 사용하여 쉽게 풀 수 있다.
입출력 예시
우선순위가 높은 프로세스를 기준으로 순차적으로 프로세스를 실행시키면서
priorities[location]에 해당하는 프로세스는 몇 번째로 실행되는지 반환하면 된다.
풀이
import java.util.*
class Solution {
fun solution(priorities: IntArray, location: Int): Int {
// 큐에 각 프로세스의 (우선순위, 인덱스) 쌍을 저장
val q = LinkedList<Pair<Int, Int>>()
for ((i, p) in priorities.withIndex()) {
q.add(Pair(i, p))
}
// 프로세스가 실행된 횟수 (prioritie[location]은 {res}번째로 실행됨)
var res = 0
// 큐가 텅빌 때까지 반복
while (q.isNotEmpty()) {
val current = q.remove() // 큐에서 가장 앞에 위치한 프로세스를 꺼낸 뒤
val (i, p) = current // 해당 프로세스의 인덱스와 우선순위를 변수로 초기화
// 현재 프로세스보다 높은 우선순위를 가진 프로세스가 있다면
if (q.any { it.second > p }){
q.add(current) // 현재 프로세스를 다시 큐에 넣음
}
// 없다면
else {
res++ // 현재 프로세스를 실행하고
if (i == location){ // 찾고자 하는 위치의 프로세스를 실행한 경우
return res // 이때까지 프로세스가 실행된 횟수 반환
}
}
}
return res // 위 로직에서 모든 프로세스를 확인하므로 이 구문은 실행되지 않음
}
}
Pair를 이용하여 각 프로세스에 번호(인덱스)를 매길 수 있다.
q.remove()는 큐의 맨 앞 요소를 제거하고 그 값을 반환한다.
q.add(current)는 현재 프로세스를 큐의 맨 뒤에다가 추가한다.
두 메소드를 활용해 큐의 요소를 순차적으로 확인할 수 있다.
현재 실행시키는 프로세스가 가장 높은 우선순위를 가진다면
프로세스를 실행해야 하므로 꺼낸 프로세스를 다시 큐에 넣지 않는다.
구조 분해 선언
fun main() {
val process = Pair(1, 2)
val (a, b) = process
print("$a + $a = $b")
}
구조 분해 선언이란 데이터 클래스나 컬렉션의 값을
분해해서 여러 변수에 한 번에 할당하는 것을 의미한다.
위와 같은 방식은 코드의 간결성과 가독성을 향상 시킬 수
있으므로 앞으로 자주 사용할 계획이다.
회고
코틀린에서 큐를 써본적이 없어서 풀이 방식을 여러가지 찾아보니까
우선순위가 높은 프로세스부터 실행한다는 점을 이용해 priorites 배열을
내림차순하여 해당 로직을 구현하는 방법도 있었고,
각 우선순위(0 ~9)에 해당하는 작업 수를 저장하는 배열을 선언해
아예 큐를 사용하지 않고 구현하는 방법도 있었다.
본인은 각 프로세스마다 인덱스를 할당한 뒤 큐를 순회하는 방식을 채택해
해당 로직을 구현했는데 해당 방식이 큐의 개념을 공부하기 가장 좋았기 때문이다.
프로세스의 우선순위에 따라 프로세스를 처리하는 로직은
queue를 사용하여 구현할 수 있다는 사실을 알게 되었다.
Queue 알아보기
Queue란?
큐는 선입선출(FIFO)의 원칙에 따라 작동하는 자료구조이다.
왜 쓰는가?
프로세스를 스케줄링할 때 큐를 사용하게 된다면
프로세스의 중요도에 따라 처리 순서를 조정할 수 있게 된다.
큐 선언하기
// java.util의 모든 클래스를 불러온다
import java.util.*
코틀린에서는 Queue가 구현되어있지 않기 때문에
java에서 구현되어 있는 Queue를 불러와야 한다.
val queue: Queue<Int> = LinkedList()
val q = LinkedList<Int>()
두 방법으로 큐를 선언할 수 있다.
Queue의 기능 정리
import java.util.*
fun main() {
val q = LinkedList<Int>() // q = []
// 큐에 요소 추가
q.add(1) // q = [1]
q.offer(2) // q = [1, 2]
q.add(3) // q = [1, 2, 3]
q.offer(4) // q = [1, 2, 3, 4]
// 큐에서 맨 앞에 있는 요소를 반환
println(q.peek()) // 출력: 1
println(q.element()) // 출력: 1
// 맨 앞에 있는 요소를 제거하고 그 값을 반환
println(q.poll()) // 출력: 1, q = [2, 3, 4]
println(q.remove()) // 출력: 2, q = [3, 4]
// 큐의 크기를 반환
println(q.size) // 출력: 2
// 큐가 비어있는지 여부를 판단
println(q.isEmpty()) // 출력: false
println(q.isNotEmpty()) // 출력: true
}
저번에 StringBuilder 알아볼 때는 관련 메소드를 하나하나 정리했는데
생각해보니까 이런식으로 정리해도 되겠다 싶었다.
안드로이드 앱 개발 입문 4주차 정리 (1)
안드로이드 4대 컴포넌트
4대 컴포넌트란?
4대 컴포넌트는 안드로이드 앱의 필수적인 기본 구성 요소이다.
4대 컴포넌트는 Activity, Broadcast Receiver, Service, Content Provider에 해당한다.
이들은 앱의 구조를 정의하고, 시스템과 어떻게 상호 작용할지를 결정한다.
각 컴포넌트 개념 정리
1. 액티비티 (Activity)
액티비티는 사용자가 직접 상호작용하는 화면을 뜻한다.
2. 서비스 (Service)
백그라운드에서 오랜 시간 동안 실행되어야 하는 작업을 수행한다.
3. 브로드캐스트 리시버 (Broadcast Receiver)
안드로이드 시스템으로부터 발송되는 다양한 이벤트나 정보를
애플리케이션이 받을 수 있게 해주는 컴포넌트이다.
4. 콘텐트 프로바이더 (Content Provider)
애플리케이션 간의 데이터 공유를 가능하게 한다.
액티비티
액티비티란?
안드로이드에서 액티비티는 사용자와 상호작용하는 창(window)을 의미한다.
각 액티비티는 독립적인 화면으로써, 사용자에게 인터페이스를 제공한다
각 액티비티는 하나의 창을 가지며,
이 창에는 View 객체들을 통해 사용자 인터페이스가 구성된다.
뷰 객체들은 사용자가 볼 수 있는 모든 요소들을 포함한다.
모든 안드로이드 앱은 최소 한 개 이상의 액티비티를 포함하고 있으며,
앱이 시작될 때 시스템은 지정된 '메인' 액티비티를 실행한다.
액티비티와 사용자 인터페이스 연결
setContentView()를 호출해 액티비티에서 실행할 View를 설정한다.
R.java 파일은 res 디렉토리 내의 모든 리소스에 대한 ID를 포함한다.
형식은 R.[리소스 유형].[리소스 이름]에 해당한다.
액티비티 등록
모든 Activity는 Manifest 파일에 등록되어야 한다.
인텐트
인텐트란?
인텐트란 컴포넌트 간의 작업을 요청하거나 정보를 전달하기 위한 메시징 객체로,
주로 화면 전환, 서비스 시작, 브로드캐스트 메시지 전송 등에 사용된다.
인텐트 유형
val intent = Intent(this, MainActivity::class.java)
startActivity(intent)
명시적 인텐트는 특정한 컴포넌트를 직접적으로 호출할 때 사용된다.
개발자는 인텐트 객체에 시작하고자 하는 구성 요소의 이름을 명확하게
설정하고 startActivity() 또는 stratService() 메소드를 통해 해당 컴포넌트를 실행시킨다.
암시적 인텐트는 주로 다른 앱의 컴포넌트를 실행시키는 데 사용된다.
특정한 컴포넌트를 명시하지 않고, 수행하고자 하는 일반적인 작업을
인텐트 객체에 설정하여 startActivity() 메소드에 넘긴다.
안드로이드 시스템은 이 인텐트를 처리할 수 있는 모든 애플리케이션을 검색해
적합한 인텐트 필터를 가진 컴포넌트를 찾아 실행시킨다.
인텐트 객체 분석하기
// 해당 인텐트는 명시적 인텐트로, TargetActivity.class가 컴포넌트 이름이다.
val intent = Intent(context, TargetActivity.class)
타겟 컴포넌트의 이름을 명시하여, 인텐트가 전달될 정확한 대상을 지정한다.
// 특정 브라우저를 여는 인텐트 선언
val intent = Intent(Intent.ACTION_VIEW)
intent.data = Uri.parse("http://www.example.com")
intent.addCategory(Intent.CATEGORY_BROWSABLE)
Intent의 액션을 지정하여 수행해야 할 일반적인 작업을 정의할 수 있다.
데이터는 보통 Uri 객체로 액션과 결합하여 사용된다.
인텐트의 카테고리를 지정하여 인텐트를 필터링을 진행한다.
intent.putExtra("extra_key", "value")
인텐트의 putExtra 메소를 이용해 키-값 쌍의 데이터를 전달한다.
액티비티 간 데이터 전달
- Intent putExtra(String name, int value)
- Intent putExtra(String name, String value)
- Intent putExtra(String name, boolean value)
액티비티에 값을 저장하는 메소드는 putExtra로 전부 동일하다.
- int getIntExtra(String name, int defaultValue)
- String getString(String name)
- boolean getBooleanExtra(String name, boolean defaultValue)
Extra에 저장된 값을 읽어오는 메소드는 읽어올 값의 자료형에 따라 달라진다.
'내일배움캠프 > Android 국비지원' 카테고리의 다른 글
TIL 31일차 (타겟 넘버 - Kotlin | 앱개발 입문 과제 필수 구현 사항) (0) | 2024.06.26 |
---|---|
TIL 30일차 (피로도 - Kotlin | 액티비티 생명주기 개념 정리) (0) | 2024.06.25 |
TIL 28일차 (기능개발 - Kotlin) (0) | 2024.06.23 |
TIL 27일차 (의상 - Kotlin) (1) | 2024.06.22 |
TIL 26일차 (할인 행사 - Kotlin | 레이아웃 개념정리 & 실습) (2) | 2024.06.21 |