如何在 Scala 中构建不可变树数据结构?
How can I build an immutable tree datastructure in Scala?
我正在尝试构建这样定义的不可变 Trie:
case class Trie(children: Map[Char, Trie] = Map.empty[Char, Trie], value: Option[String] = None)
使用以下扩展方法:
extension (t: Trie)
def addAll(words: Seq[String]): Trie =
words.foldLeft(new Trie())(_.insert(_))
def insert(word: String): Trie =
var cur = t
word.foreach(c => {
if !cur.children.contains(c) then
cur = cur.copy(children = cur.children + (c -> new Trie()))
end if
cur = cur.children.get(c).get
})
cur.copy(value = Some(word))
我目前的问题是具体 insert
方法:我尝试了多种不同的方法,但我所有的尝试都未能 return Trie 的根,即我是无法以从根节点到叶子的整个分支与新插入的节点一起复制的方式插入新节点。
为了进一步说明,如下:
@main def hello: Unit =
println(new Trie().insert("bot").insert("bat"))
简单地导致:Trie(Map(),Some(bat))
总的来说,我是 Scala 和 FP 的新手,所以我不确定这里的最佳方法。
这似乎达到了您的目的。
case class Trie(children : Map[Char, Trie] = Map()
,value : Option[String] = None):
def insert(word: String, index: Int = 0): Trie =
word.lift(index).fold(copy(value=Some(word))){c =>
copy(children + (c -> children.getOrElse(c,Trie()).insert(word, index+1)))
}
测试:
Trie().insert("inn").insert("in")
//Trie(Map(i -> Trie(Map(n -> Trie(Map(n -> Trie(Map(),Some(inn))),Some(in))),None)),None)
我正在尝试构建这样定义的不可变 Trie:
case class Trie(children: Map[Char, Trie] = Map.empty[Char, Trie], value: Option[String] = None)
使用以下扩展方法:
extension (t: Trie)
def addAll(words: Seq[String]): Trie =
words.foldLeft(new Trie())(_.insert(_))
def insert(word: String): Trie =
var cur = t
word.foreach(c => {
if !cur.children.contains(c) then
cur = cur.copy(children = cur.children + (c -> new Trie()))
end if
cur = cur.children.get(c).get
})
cur.copy(value = Some(word))
我目前的问题是具体 insert
方法:我尝试了多种不同的方法,但我所有的尝试都未能 return Trie 的根,即我是无法以从根节点到叶子的整个分支与新插入的节点一起复制的方式插入新节点。
为了进一步说明,如下:
@main def hello: Unit =
println(new Trie().insert("bot").insert("bat"))
简单地导致:Trie(Map(),Some(bat))
总的来说,我是 Scala 和 FP 的新手,所以我不确定这里的最佳方法。
这似乎达到了您的目的。
case class Trie(children : Map[Char, Trie] = Map()
,value : Option[String] = None):
def insert(word: String, index: Int = 0): Trie =
word.lift(index).fold(copy(value=Some(word))){c =>
copy(children + (c -> children.getOrElse(c,Trie()).insert(word, index+1)))
}
测试:
Trie().insert("inn").insert("in")
//Trie(Map(i -> Trie(Map(n -> Trie(Map(n -> Trie(Map(),Some(inn))),Some(in))),None)),None)