Created
March 18, 2022 04:25
-
-
Save cherrydev/cff792b6208424189ed4be0c21f2ab7b to your computer and use it in GitHub Desktop.
Fast functions for intersecting sorted lists in Kotlin, returning Lists or Sequences
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import kotlin.math.* | |
object ListIntersection { | |
fun <T : Comparable<T>> safeIntersection(l1: List<T>, l2: List<T>) : List<T> { | |
return l1.intersect(l2).sorted() | |
} | |
// https://stackoverflow.com/a/33963306/480176 | |
fun <T : Comparable<T>> fastIntersection(a1: List<T>, a2: List<T>) : List<T> { | |
return fastIntersectionSequence(a1, a2).toList() | |
} | |
fun <T : Comparable<T>> fastIntersectionSequence(a1: List<T>, a2: List<T>) : Sequence<T> { | |
val s1 = a1.size | |
val s2 = a2.size | |
return if (s1 > 0 && s1 + s2 > min(s1, s2) * ln(max(s1, s2).toDouble()) * 1.4426950408889634) | |
bSearchIntersectionSequence(a1, a2) | |
else | |
linearIntersectionSequence(a1, a2) | |
} | |
fun <T : Comparable<T>> linearIntersectionSequence(a1: List<T>, a2: List<T>) : Sequence<T> { | |
return sequence { | |
val s1 = a1.size | |
val s2 = a2.size | |
var i1 = 0 | |
var i2 = 0 | |
while (i1 < s1 && i2 < s2) { | |
val v1 = a1[i1] | |
val v2 = a2[i2] | |
if (v1 == v2) { | |
yield(v1) | |
i1 += 1 | |
i2 += 1 | |
} | |
else if (v1 < v2) i1 += 1 | |
else i2 += 1 | |
} | |
} | |
} | |
fun <T : Comparable<T>> bSearchIntersectionSequence(a1: List<T>, a2: List<T>) : Sequence<T> { | |
return sequence { | |
val s1 = a1.size | |
val s2 = a2.size | |
var i1 = 0 | |
var i2 = 0 | |
var temp : Int | |
while (i1 < s1 && i2 < s2) { | |
val v1 = a1[i1] | |
val v2 = a2[i2] | |
if (v1 == v2) { | |
yield(v1) | |
i1 += 1 | |
i2 += 1 | |
} | |
else if (v1 < v2) { | |
temp = a1.binarySearch(v2, i1) | |
i1 = if (temp < 0) -(temp + 1) else temp | |
} | |
else { | |
temp = a2.binarySearch(v1, i2) | |
i2 = if (temp < 0) -(temp + 1) else temp | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment