code simplification

improved unit tests
This commit is contained in:
2019-12-14 13:13:36 +00:00
parent d6727ddad1
commit 38b5416752
2 changed files with 124 additions and 53 deletions

View File

@@ -102,9 +102,19 @@ interface ILevTrie : ICharTrie<IntArray> {
fun fuzzySearch(word : String, maxResult: Int) : List<Pair<String, Int>> {
val result = sortedSetOf<Pair<String, Int>>(compareBy({ it.second }, { it.first }))
val requiredSize = word.length + 1
fun visitNode(stack: List<StackContext<LevNode, Unit>>) : TreeNodeVisitor.VisitOutcome {
if(stack.size > 1) {
val visitor = object: TreeNodeVisitor<LevNode, Unit> {
override fun visitPre(stack: List<StackContext<LevNode, Unit>>): TreeNodeVisitor.VisitOutcome {
val currentStackElement = stack.last()
val currentNode = currentStackElement.node
if(currentNode.payload == null ||
currentNode.payload!!.size < requiredSize) {
if(stack.size == 1) {
currentNode.payload = IntArray(requiredSize) { i -> i }
} else {
currentNode.payload = IntArray(requiredSize) { i -> if(i == 0) stack.size - 1 else 0 }
}
}
if(stack.size > 1) {
if(currentStackElement.node.key == null) {
val sb = StringBuilder()
for(c in currentStackElement.node.linealDescendant()) {
@@ -125,23 +135,6 @@ interface ILevTrie : ICharTrie<IntArray> {
return TreeNodeVisitor.VisitOutcome.CONTINUE
}
}
val visitor = if(root.payload == null || root.payload!!.size < requiredSize) {
object: TreeNodeVisitor<LevNode, Unit> {
override fun visitPre(stack: List<StackContext<LevNode, Unit>>): TreeNodeVisitor.VisitOutcome {
val currentNode = stack.last()
if(stack.size == 1) {
currentNode.node.payload = IntArray(requiredSize) { i -> i }
} else {
currentNode.node.payload = IntArray(requiredSize) { i -> if(i == 0) stack.size - 1 else 0 }
}
visitNode(stack)
return TreeNodeVisitor.VisitOutcome.CONTINUE
}
}
} else object: TreeNodeVisitor<LevNode, Unit> {
override fun visitPre(stack: List<StackContext<LevNode, Unit>>): TreeNodeVisitor.VisitOutcome {
return visitNode(stack)
}
}
val walker = TreeWalker<LevNode, Unit>(visitor)
walker.walk(root)

View File

@@ -1,33 +1,111 @@
package net.woggioni.klevtree
import org.junit.Assert
import org.junit.Test
import java.io.BufferedReader
import java.io.InputStreamReader
class LevtreeTest {
@Test
fun foo() {
val reader = BufferedReader(
InputStreamReader(javaClass.getResourceAsStream("/cracklib-small")))
fun trivialTest() {
val tree = LevTrie()
tree.caseSensitive = false
try {
for(line in reader.lines()) {
tree.add(line.asIterable())
}
} finally {
reader.close()
}
println(tree.add("dailies"))
var node = tree.search("dailies")
println(node!!.linealDescendant())
tree.remove("dailies")
node = tree.search("dailies")
println(node)
tree.algorithm = ILevTrie.Algorithm.DAMERAU_LEVENSHTEIN
val result = tree.fuzzySearch("daiiles", 5)
println(result)
val word = "dailies"
run {
val pair = tree.add(word)
Assert.assertTrue(pair.first)
val node = tree.search(word)
Assert.assertNotNull(node)
Assert.assertEquals(
word,
node!!.linealDescendant().fold(StringBuilder(), StringBuilder::append).toString()
)
val result = tree.fuzzySearch(word, 5)
Assert.assertEquals(1, result.size)
Assert.assertEquals(word to 0, result[0])
}
run {
tree.remove(word)
val node = tree.search(word)
Assert.assertNull(node)
val result = tree.fuzzySearch(word, 5)
Assert.assertEquals(0, result.size)
}
}
private fun initLevTrie() : LevTrie {
val words = listOf(
"tired",
"authorise",
"exercise",
"bloody",
"ritual",
"trail",
"resort",
"landowner",
"navy",
"captivate",
"captivity",
"north")
return run {
val res = LevTrie()
words.forEach {res.add(it)}
res
}
}
@Test
fun levenshteinDistanceTest() {
val tree = initLevTrie()
tree.caseSensitive = false
tree.algorithm = ILevTrie.Algorithm.LEVENSHTEIN
run {
val word = "fired"
val result = tree.fuzzySearch(word, 4)
Assert.assertEquals(4, result.size)
Assert.assertEquals("tired" to 1, result[0])
}
run {
val word = "tierd"
val result = tree.fuzzySearch(word, 4)
Assert.assertEquals(4, result.size)
Assert.assertEquals("tired" to 2, result[0])
}
run {
val word = "tierd"
tree.remove("tired")
val result = tree.fuzzySearch(word, 4)
Assert.assertEquals(4, result.size)
Assert.assertEquals("trail" to 4, result[0])
}
}
@Test
fun damerauLevenshteinDistanceTest() {
val tree = initLevTrie()
tree.caseSensitive = false
tree.algorithm = ILevTrie.Algorithm.DAMERAU_LEVENSHTEIN
run {
val word = "fired"
val result = tree.fuzzySearch(word, 4)
Assert.assertEquals(4, result.size)
Assert.assertEquals("tired" to 1, result[0])
}
run {
val word = "capitvate"
val result = tree.fuzzySearch(word, 4)
Assert.assertEquals(4, result.size)
Assert.assertEquals("captivate" to 1, result[0])
Assert.assertEquals("captivity" to 3, result[1])
}
run {
tree.remove("captivate")
val word = "capitvate"
val result = tree.fuzzySearch(word, 4)
Assert.assertEquals(4, result.size)
Assert.assertEquals("captivity" to 3, result[0])
}
}
}