Skip to main content

Edit Distance

package algorithmdesignmanualbook.dynamic

import kotlin.system.measureTimeMillis
import kotlin.test.assertTrue

private fun editDistance(str1: String, str2: String, m: Int, n: Int): Int {
// str2 insertion
if (m == 0) {
return n
}
// str1 insertion
if (n == 0) {
return m
}

// no changes. shift both to lower index for compare
if (str1[m - 1] == str2[n - 1]) {
return editDistance(str1, str2, m - 1, n - 1)
}
return 1 + listOf(
editDistance(str1, str2, m - 1, n), //Insert
editDistance(str1, str2, m, n - 1), // Delete
editDistance(str1, str2, m - 1, n - 1), // Replace
).minOrNull()!!
}


private fun editDistance(str1: String, str2: String, m: Int, n: Int, mem: Array<Array<Int>>): Int {
// str2 insertion
if (m == 0) {
mem[m][n] = n
return n
}
// str1 insertion
if (n == 0) {
mem[m][n] = m
return m
}

// no changes. shift both to lower index for compare
if (str1[m - 1] == str2[n - 1]) {
val distance = editDistance(str1, str2, m - 1, n - 1, mem)
mem[m - 1][n - 1] = distance
return distance
}
val insert = editDistance(str1, str2, m - 1, n, mem)
mem[m - 1][n] = insert

val delete = editDistance(str1, str2, m, n - 1, mem)
mem[m][n - 1] = delete

val replace = editDistance(str1, str2, m - 1, n - 1, mem)
mem[m - 1][n - 1] = replace

return 1 + listOf(
insert, //Insert
delete, // Delete
replace, // Replace
).minOrNull()!!

}

fun main() {
run {
val (str1, str2) = Pair("saturday", "friday")
assertTrue {
editDistance(str1, str2, str1.length, str2.length) == 5
}
}

run {
val (str1, str2) = Pair("saturday", "sunday")
measureTimeMillis {
assertTrue {
editDistance(str1, str2, str1.length, str2.length) == 3
}
}
measureTimeMillis {
assertTrue {
editDistance(str1, str2, str1.length, str2.length, Array(str1.length) { Array(str2.length) { 0 } }) == 3
}
}

}

}

Updated on 2021-04-03