/** * file: dpLcsMaximizer.kt * author: San Skulrattanakulchai * date: 2018-11-02 * * This program differs from `dpLcs.kt` in that it uses both the * dp table `opt` and the maximizer table `maxer`. */ fun main(args: Array) { val x = readLine()!! val y = readLine()!! fun String.explode() = this.toList().joinToString(separator=" ") println(""" |x: ${x.explode()} |y: ${y.explode()} |LCS(x, y): ${dpLcs(x, y).explode()} """.trimMargin()) } enum class Dir { NONE, RIGHT, DOWN, DIAG } fun dpLcs(x: String, y: String): String { val m = x.length val n = y.length val opt = Array(m+1) { IntArray(n+1) } val maxer = Array>(m) { Array(n) { Dir.NONE } } fun fillTable() { for (i in m-1 downTo 0) { for (j in n-1 downTo 0) { if (x[i] == y[j]) { opt[i][j] = opt[i+1][j+1] + 1 maxer[i][j] = Dir.DIAG } else if (opt[i+1][j] > opt[i][j+1]) { opt[i][j] = opt[i+1][j] maxer[i][j] = Dir.DOWN } else { opt[i][j] = opt[i][j+1] maxer[i][j] = Dir.RIGHT } } } } fun lcs(): String { val sb = StringBuilder() var i = 0 var j = 0 while ((i < m) && (j < n)) { when (maxer[i][j]) { Dir.DIAG -> { sb.append(x[i]) i++ j++ } Dir.DOWN -> i++ Dir.RIGHT -> j++ else -> throw Exception("Incorrect maximizer value.") } } return sb.toString() } fillTable() return(lcs()) }