코틀린으로 비트마스킹 팁 (백준 11723 집합 - Kotlin)

jibmin jung·2022년 5월 8일
1

코틀린으로 비트마스킹 팁
비트마스킹은 bit 단위의 조작을 통해 적은 메모리로 여러 원소들의 상태나 정보를 기록해두는 방식입니다.
kotlin은 다른 언어들과는 다른 비트연산자 모양을 가지고 있습니다.
코테에 종종 나오므로 사용법을 정리하고,
편하게 쓸 수 있도록 infix 함수를 만들었습니다.

0. infix 함수를 이용해 비트 연산 함수 만들기

infix 함수를 이용해 간단하게 쓸 수 있도록 만들었습니다.

infix fun Int.on(i:Int) = this or (1 shl i-1)
infix fun Long.on(i:Int) = this or (1L shl i-1)

infix fun Int.off(i:Int) = this and (1 shl i-1).inv()
infix fun Long.off(i:Int) = this and (1L shl i-1).inv()

infix fun Int.chk(i:Int) = if(this and (1 shl i-1)>=1) 1 else 0
infix fun Long.chk(i:Int) = if(this and (1L shl i-1)>=1L) 1 else 0

infix fun Int.toggle(i:Int) = this xor (1 shl i-1)
infix fun Long.toggle(i:Int) = this xor (1L shl i-1)

1. i 번째 비트 켜기

	//w/o infix fun
	state = state or (1 shl i-1)
    // w infix fun
    state = state on i

2. i 번째 비트 끄기

	//w/o infix fun
	state = state and (1 shl i-1).inv()
    // w infix fun
    state = state off i

3. i 번째 비트 확인하기

	//w/o infix fun
	result = if(state and (1 shl i-1)>=1) 1 else 0
    // w infix fun
    result = state chk i

4. i 번째 비트 전환(토글)

	//w/o infix fun
	state = state xor (1 shl i-1)
    // w infix fun
    state = state toggle i

5. i 번째 밑으로 다 끄기

	state = state and ((1 shl i)-1).inv()

6. i 번째 위로 다 끄기

	state = state and ((1 shl i-1)-1)

7. 이진수로 출력

	// when state = 100101 (2)
	println(state.toString(2))
    // 100101

8. 이진수 문자열을 숫자로

	println("1111111111111111111111111111111".toInt(2)) //2147483647
    println("11111111111111111111111111111111".toInt(2)) //NumberFormatException
    println("11111111111111111111111111111111".toLong(2)) //4294967295

9. 문제 활용 - 백준 11723

링크

https://www.acmicpc.net/problem/11723

코드

import java.io.BufferedReader
import java.io.InputStreamReader

val sb = StringBuilder()
fun main()=with(BufferedReader(InputStreamReader(System.`in`))){
    var set = 0L
    repeat(readLine().toInt()) {
        val order = readLine().split(" ")
        val n = order.last().toIntOrNull()?:0
        when (order.first()) {
            "add" -> set = set on n
            "remove" -> set = set off n
            "check" -> sb.append(set chk n).append("\n")
            "toggle" -> set = set toggle n
            "all" -> set = set or 0L.inv()
            "empty" -> set = 0L
        }
    }
    println(sb)
}

infix fun Int.on(i:Int) = this or (1 shl i-1)
infix fun Long.on(i:Int) = this or (1L shl i-1)

infix fun Int.off(i:Int) = this and (1 shl i-1).inv()
infix fun Long.off(i:Int) = this and (1L shl i-1).inv()

infix fun Int.chk(i:Int) = if(this and (1 shl i-1)>=1) 1 else 0
infix fun Long.chk(i:Int) = if(this and (1L shl i-1)>=1L) 1 else 0

infix fun Int.toggle(i:Int) = this xor (1 shl i-1)
infix fun Long.toggle(i:Int) = this xor (1L shl i-1)
profile
이것저것 안드로이드

0개의 댓글