55 lines
1.4 KiB
Kotlin
55 lines
1.4 KiB
Kotlin
package com.infendro.cli.util
|
|
|
|
internal const val threshold = 2
|
|
|
|
/**
|
|
* Calculates the Damerau-Levenshtein distance between two strings.
|
|
*
|
|
* The distance is the minimum number of operations (insertion, deletion, substitution, and transposition) required to transform one string into another.
|
|
*
|
|
* @param a The source string.
|
|
* @param b The target string.
|
|
* @return The minimum number of operations to transform [a] into [b].
|
|
*/
|
|
internal fun distance(a: String, b: String): Int {
|
|
if (a == b) return 0
|
|
|
|
val n = a.length
|
|
val m = b.length
|
|
|
|
if (n == 0) return m
|
|
if (m == 0) return n
|
|
|
|
var prev2 = IntArray(m + 1)
|
|
var prev1 = IntArray(m + 1) { it }
|
|
var curr = IntArray(m + 1)
|
|
|
|
for (i in 1..n) {
|
|
curr[0] = i
|
|
for (j in 1..m) {
|
|
val cost = if (a[i - 1] == b[j - 1]) 0 else 1
|
|
|
|
curr[j] = minOf(
|
|
prev1[j] + 1, // deletion
|
|
curr[j - 1] + 1, // insertion
|
|
prev1[j - 1] + cost, // substitution
|
|
)
|
|
|
|
// transposition
|
|
if (i > 1 && j > 1 && a[i - 1] == b[j - 2] && a[i - 2] == b[j - 1]) {
|
|
curr[j] = minOf(
|
|
curr[j],
|
|
prev2[j - 2] + 1,
|
|
)
|
|
}
|
|
}
|
|
|
|
val tmp = prev2
|
|
prev2 = prev1
|
|
prev1 = curr
|
|
curr = tmp
|
|
}
|
|
|
|
return prev1[m]
|
|
}
|