[Kotlin] 알고리즘 - 순열(Permutation)
Kotlin순열(Permutation)
서로 다른 n개를 가진 원소에서 r개를 중복없이 골라 순서대로 나열한다.
조합에서 확장된 개념으로, 조합과 달리 순서가 있다.
방문 여부 배열을 이용한 처리 과정
- 깊이 우선 탐색(DFS, Depth-First Search)으로 모든 원소를 방문한다.
- 방문 여부를 확인하여 값이 중복되지 않게 한다.
- 깊이가 r과 일치할 때까지 위 과정을 반복한다.
코드 1. n!
kotlin
private const val alphabets = "ABC"
private lateinit var result: Array<Char> // 정렬된 알파벳
private lateinit var visited: Array<Boolean> // 순열 방문 여부
fun main() {
result = Array(alphabets.length) { '_' }
visited = Array(alphabets.length) { false }
permutation()
}
fun permutation(depth: Int = 0) {
if (depth == alphabets.length) {
println(result.contentDeepToString()) // 완성된 순열
return
}
for (i in alphabets.indices) {
if (visited[i]) continue
result[depth] = alphabets[i]
visited[i] = true
permutation(depth + 1)
visited[i] = false
}
}
코드 2. nPr + 제네릭 타입으로 모든 데이터 타입 대응
kotlin
fun main() {
permutation(arrayOf("A", "B", "C"), 3).forEach {
println(it)
}
}
/**
* 순열
*
* @param elements: n개 원소를 가진 배열
* @param r: 추출할 원소 수
*/
fun <T> permutation(elements: Array<T>, r: Int): List<List<T>> {
val visited = BooleanArray(elements.size) // 방문 여부
val results = mutableListOf<List<T>>() // 모든 경우의 수
val result = elements.sliceArray(0 until r) // r개를 정렬한 결과
fun recursionPermutation(depth: Int = 0) {
if (depth == r) {
results.add(result.toList())
return
}
for (i in elements.indices) {
if (visited[i]) continue
visited[i] = true
result[depth] = elements[i]
recursionPermutation(depth + 1)
visited[i] = false
}
}
recursionPermutation()
return results
}
코드 3. nPr + swap을 이용한 처리
kotlin
fun main() {
permutation(arrayOf("A", "B", "C"), 3).forEach {
println(it)
}
}
fun <T> permutation(elements: Array<T>, r: Int): List<List<T>> {
val n = elements.size
val results = mutableListOf<List<T>>() // 모든 경우의 수
fun swapPermutation(depth: Int = 0) {
if (depth == r) {
results.add(elements.takeLast(r).toList())
return
}
for (i in range(depth, n)) {
var tmp = elements[i]
elements[i] = elements[depth]
elements[depth] = tmp
swapPermutation(depth + 1)
// 원위치
tmp = elements[i]
elements[i] = elements[depth]
elements[depth] = tmp
}
}
swapPermutation()
return results
}
결과
text
[A, B, C]
[A, C, B]
[B, A, C]
[B, C, A]
[C, A, B]
[C, B, A]
Reference
https://velog.io/@chayezo/Algorithm-순열-조합
https://hanyeop.tistory.com/455
https://notepad96.tistory.com/111
https://programming4myself.tistory.com/94
https://velog.io/@soyeon207/알고리즘-순열-yaxs0hh7
https://gyeong-log.tistory.com/51
https://soopeach.tistory.com/157
https://velog.io/@heyday_7/알고리즘-순열과-조합