티스토리 뷰
사전캠프 TIL 11일차 (크기가 작은 부분 문자열, 최소직사각형 - Kotlin | 로또 번호 생성기 기능 구현)
하몬드 2024. 5. 8. 15:46코드카타
크기가 작은 부분 문자열
문제
정답
class Solution {
fun solution(t: String, p: String): Int {
val arr = arrayListOf<String>()
for (i in 0..(t.length - p.length + 1)) {
if (i + p.length - 1 < t.length) {
arr.add(t.substring(i, i + p.length))
}
}
var res: Int = 0
for (i in 0 until arr.size) {
if (arr[i] <= p) {
res += 1
}
}
return res
}
}
나같은 경우는 빈 배열을 하나 선언해 거기다 부분 문자열을 추가하고
그 배열의 요소를 하나하나 검사하는 방식으로 풀었다.
다른 풀이
class Solution {
fun solution(t: String, p: String): Int { // 7 3
return (0..t.length - p.length)
.map{ t.substring(it until it + p.length) }
.count { it <= p }
}
}
0 ~ t 문자열 길이 - p 문자열 길이의 범위에서 map함수를 통해 부분문자열이 담긴 배열을 만들고,
count 함수를 통해 배열의 요소들 중 p보다 작거나 같은 요소의 수를 반환한다
최소직사각형
문제
정답
class Solution {
fun solution(sizes: Array<IntArray>): Int {
val a = sizes.map { it.maxOrNull()!! }.maxOrNull()!!
val b = sizes.map { it.minOrNull()!! }.maxOrNull()!!
return a * b
}
}
명함마다 가로 세로 길이를 비교해
큰 값들중에 가장 큰 값과 작은 값들중에 가장 큰값을 곱하면 된다.
maxOrNull() 과 minOrNull() 함수의 반환값은 Int?형이므로
'!!'연산자를 사용해 해당 변수가 null값이 아님을 단언해줘야 한다.
로또 번호 생성기 기능 구현
서클 설정
android:visibility="gone"
로또 번호 생성기의 초기 화면은 LinearLayout에
아무런 번호도 없어야 하기 때문에 6개의 원들을 보이지 않게 설정해준다.
변수 선언
private val clearButton by lazy { findViewById<Button>(R.id.btn_clear) }
private val addButton by lazy { findViewById<Button>(R.id.btn_add) }
private val runButton by lazy { findViewById<Button>(R.id.btn_run) }
private val numPick by lazy { findViewById<NumberPicker>(R.id.np_num) }
private val numTextViewList : List<TextView> by lazy {
listOf<TextView>(
findViewById(R.id.tv_num1),
findViewById(R.id.tv_num2),
findViewById(R.id.tv_num3),
findViewById(R.id.tv_num4),
findViewById(R.id.tv_num5),
findViewById(R.id.tv_num6)
)
}
초기화 버튼, 번호 추가 버튼, 자동 생성 시작 버튼, NumberPicker 위젯,
6개의 원(TextView)이 들어있는 리스트 이렇게 총 5개의 변수를 선언해준다.
lazy 키워드는 해당 변수가 실제로 쓰일 때까지 초기화를 지연시키는 역할을 한다.
lazy를 사용하면 해당 변수들이 실제로 사용되기 전까지는 메모리에 로드되지 않으므로,
초기 리소스 로딩을 최소화할 수 있어 앱의 초기 실행 속도를 개선할 수 있게 된다.
'private'로 선언된 멤버는 클래스 외부에서 접근할 수 없게 된다.
이는 클래스의 데이터가 예측 가능한 방식으로만 변경되도록 하여 프로그램의 안정성을 높인다.
또한 'private'를 사용하여 불필요한 세부 사항을 숨김으로써,
클래스를 사용하는 사용자는 필요한 기능에만 집중할 수 있게 된다.
private var didRun = false
private var pickNumberSet = hashSetOf<Int>()
자동 생성 시작 버튼의 실행여부를 체크하는 변수 didRun,
사용자가 지정한 숫자를 임시로 저장할 공간 pickNumberSet을 선언해준다.
hashSetOf<T>()
val numbers = hashSetOf(1, 2, 3, 4, 5)
println(numbers) // [1, 2, 3, 4, 5]
HashSetOf 컬렉션은 리스트와 동일한 자료형의 값을 반환한다.
이 컬렉션은 같은 값을 가진 요소의 중복 저장을 허용하지 않고,
요소의 추가, 삭제, 검색 작업이 매우 빠르다는 특징이 있다.
pickNumberSet의 초기값을 해당 컬렉션으로 선언함으로써
사용자는 중복된 숫자를 선택할 수 없게 된다.
onCreate()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
numPick.minValue = 1
numPick.maxValue = 45
initAddButton()
initRunButton()
initClearButton()
}
사용되는 변수들의 초기화를 담당하는 함수이다.
NumberPicker 위젯의 선택값을 1~45의 범위로 제한하고
각각의 버튼들을 눌렀을 때의 동작을 함수를 통해 지정한다.
initAddButton()
private fun initAddButton(){
addButton.setOnClickListener{
when{
didRun -> showToast("초기화 후에 시도해주세요")
pickNumberSet.size >= 5 -> showToast("숫자는 최대 5개까지 선택할 수 있습니다.")
pickNumberSet.contains(numPick.value) -> showToast("이미 선택된 숫자입니다.")
else -> {
val textView = numTextViewList[pickNumberSet.size]
textView.isVisible = true
textView.text = numPick.value.toString()
setNumBack(numPick.value, textView)
pickNumberSet.add(numPick.value)
}
}
}
}
'번호 추가하기' 버튼을 눌렀을 때의 동작을 정의하는 함수이다.
when 표현식을 사용해 여러 조건에 따라 다른 작업을 수행한다.
private fun showToast(message: String) {
Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
}
문자열 메시지를 인자값으로 받아 토스트 메시지를 보여주는 함수이다.
didRun -> showToast("초기화 후에 시도해주세요")
자동 생성 시작 버튼을 눌렀을 때 didRun은 true로 초기화 된다.
자동 생성 버튼이 실행되면 번호 6개가 전부 추가되어서 번호를 더 이상 추가할 수 없게 된다.
따라서 didRun이 true값을 가지고 있다면 초기화 후에 시도하라는 토스트 메시지를 띄운다.
pickNumberSet.size >= 5 -> showToast("숫자는 최대 5개까지 선택할 수 있습니다.")
pickNumberSet.contains(numPick.value) -> showToast("이미 선택된 숫자입니다.")
사용자가 최대 5개까지만 번호를 선택할 수 있도록 제한하고,
이미 선택한 숫자를 다시 선택하지 못하도록 한다.
private fun setNumBack(number: Int, textView: TextView) {
val background = when (number) {
in 1..10 -> R.drawable.circle_yellow
in 11..20 -> R.drawable.circle_blue
in 21..30 -> R.drawable.circle_red
in 31..40 -> R.drawable.circle_gray
else -> R.drawable.circle_green
}
textView.background = ContextCompat.getDrawable(this, background)
}
선택한 번호에 따라 원의 배경색을 초기화하는 함수이다.
else -> {
val textView = numTextViewList[pickNumberSet.size]
textView.isVisible = true
textView.text = numPick.value.toString()
setNumBack(numPick.value, textView)
pickNumberSet.add(numPick.value)
}
위 3개의 조건에 해당하지 않는다면 번호를 추가한다.
추가할 textView를 numTextViewList[pickNumberSet.size]로 설정해 순서대로 번호가 추가 되도록한다.
원의 중앙에 들어갈 text값은 선택한 번호로 초기화 해준고 원의 배경색도 초기화해준다.
원의 초기 visible값은 gone(숨김)이므로 true로 설정해서 원을 보이게 해준다.
마지막으로 pickNumberset 배열에 선택한 번호를 추가해 선택한 번호를 저장한다.
initClearButton()
private fun initClearButton() {
clearButton.setOnClickListener {
pickNumberSet.clear()
numTextViewList.forEach { it.isVisible = false }
didRun = false
numPick.value = 1
}
}
'초기화' 버튼을 눌렀을 때의 동작을 정의하는 함수이다.
사용자가 선택한 번호를 저장한 배열을 빈 배열로 초기화 해주고,
LinearLayout 안에 들어있는 모든 원들을 보이지 않게 한다.
didRun을 false로 초기화해 번호를 추가할 수 있도록 하고,
numberPicker위젯의 초기값을 설정해둔 최소값으로 초기화한다.
getRandom()
private fun getRandom(): List<Int> {
val numbers = (1..45).filter { it !in pickNumberSet }
return (pickNumberSet + numbers.shuffled().take(6 - pickNumberSet.size)).sorted()
}
조건에 맞는 랜덤한 번호를 생성하는 함수이다.
numbers는 사용자가 선택한 번호를 제외한 1~45 범위의 숫자가 담긴 배열에 해당한다.
해당 함수는 '사용자가 선택한 번호 + 섞인 번호들 중 (6 - 선택한 번호 개수)개'가
요소로 들어있는 Int형 배열을 오름차순으로 정렬한 값을 반환한다.
initRunButton()
private fun initRunButton() {
runButton.setOnClickListener {
val list = getRandom()
didRun = true
list.forEachIndexed { index, number ->
val textView = numTextViewList[index]
textView.text = number.toString()
textView.isVisible = true
setNumBack(number, textView)
}
}
}
'자동 생성 시작' 버튼을 눌렀을 때의 동작을 정의하는 함수이다.
'list'를 (선택한 번호 + 랜덤한 숫자)가 담긴 리스트로 초기화하고
번호 추가하기 버튼의 함수와 동일한 방식으로
번호('list'의 요소값)를 순서대로 추가해준다.
테스트
'내일배움캠프 > Android 사전캠프' 카테고리의 다른 글
사전캠프 TIL 13일차 (문자열 내 마음대로 정렬하기 - Kotlin | MBTI 테스트 질문지 화면 UI) (0) | 2024.05.10 |
---|---|
사전캠프 TIL 12일차 (시저 암호, 숫자 문자열과 영단어 - Kotlin | MBTI 테스트 시작화면 UI 구현) (0) | 2024.05.09 |
사전캠프 TIL 10일차 (이상한 문자 만들기, 삼총사 - Kotlin | 로또 번호 생성기 UI 구현) (0) | 2024.05.07 |
사전캠프 TIL 9일차 (3진법 뒤집기 - Kotlin | BMI 계산 기능 구현) (0) | 2024.05.04 |
사전캠프 TIL 8일차 (직사각형 별찍기, 최대공약수와 최대공배수 - Kotlin) (1) | 2024.05.02 |