Skip to content

Instantly share code, notes, and snippets.

@pshirshov
Created October 31, 2019 15:38
Show Gist options
  • Save pshirshov/d9e14f48f6c9f6e5038d05f7c1bb81bc to your computer and use it in GitHub Desktop.
Save pshirshov/d9e14f48f6c9f6e5038d05f7c1bb81bc to your computer and use it in GitHub Desktop.
Simple prefix search tree (trie)
case class PrefixTree[K, V](values: Seq[V], children: Map[K, PrefixTree[K, V]]) {
def findSubtree(prefix: List[K]): Option[PrefixTree[K, V]] = {
prefix match {
case Nil =>
Some(this)
case head :: tail =>
children.get(head).map(_.findSubtreeOrRoot(tail))
}
}
def findSubtreeOrRoot(prefix: List[K]): PrefixTree[K, V] = {
prefix match {
case Nil =>
this
case head :: tail =>
children.get(head) match {
case Some(value) =>
value.findSubtreeOrRoot(tail)
case None =>
this
}
}
}
def subtreeValues: Seq[V] = {
values ++ children.values.flatMap(_.subtreeValues)
}
}
object PrefixTree {
def build[P, V](pairs: Seq[(Seq[P], V)]): PrefixTree[P, V] = {
val (currentValues, subValues) = pairs.partition(_._1.isEmpty)
val next = subValues
.map {
case (k :: tail, v) =>
(k, (tail, v))
}
.groupBy(_._1)
.toSeq
.map {
case (k, group) =>
k -> build(group.map(_._2))
}
.toMap
PrefixTree(currentValues.map(_._2), next)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment