我有以下类型的单词DAG:HashMap[String, Set[String]]
。我想建立一个通过图表的所有路径的集合。但是我写的方法并没有像我期望的那样:
def buildChain(wordGraph: HashMap[String, Set[String]], path: ListBuffer[String], accumChains: ListBuffer[ListBuffer[String]]): ListBuffer[ListBuffer[String]] = {
val children = wordGraph(path.last)
for (word <- children) {
path += word
if (wordGraph.keySet.contains(word)) buildChain(wordGraph, path, accumChains)
else accumChains += path
}
return accumChains
}
当我传递此图表时:
Map("chow" -> Set("how", "cho", "cow"), "how" -> Set("ho", "ow"), "cho" -> Set("ho"), "cow" -> Set("ow"))
我希望得到:
ListBuffer(ListBuffer("chow", "how", "ho"), ListBuffer("chow", "how", "ow"), ListBuffer("chow", "cho", "ho"), ListBuffer("chow", "cow", "ow"))
当我从“chow”开始。
相反,我得到了这个:
ListBuffer(ListBuffer(chow, how, ho, ow, cho, ho, cow, ow), ListBuffer(chow, how, ho, ow, cho, ho, cow, ow), ListBuffer(chow, how, ho, ow, cho, ho, cow, ow), ListBuffer(chow, how, ho, ow, cho, ho, cow, ow))
我无法弄明白为什么。我确信这很简单,但我现在就错过了它。
答案 0 :(得分:2)
当您为path += word
中的每个word
执行行children
时,您将附加到相同的缓冲区,因此只会增长以容纳所有子项(并且相同的缓冲区是然后多次添加到accumChains
)。您想为每个单词生成一个新序列。我可以建议在这里使用不可变列表吗?
答案 1 :(得分:2)
这是一个简单的解决方案,我对param类型进行了一些改动,因为我认为不可变类型足够好:
def _buildChain(wordGraph: Map[String, Set[String]], path: String): List[List[String]] = {
wordGraph.get(path) match {
case Some(w) => w.toList.flatMap(_buildChain(wordGraph, _).map(path :: _))
case None => List(List(path))
}
}
def buildChain(wordGraph: Map[String, Set[String]], path: List[String]): List[List[String]] = path.flatMap(_buildChain(wordGraph, _))
val a = _buildChain( Map("chow" -> Set("how", "cho", "cow"), "how" -> Set("ho", "ow"), "cho" -> Set("ho"), "cow" -> Set("ow")), "chow")
println(a)
val b = buildChain( Map("chow" -> Set("how", "cho", "cow"), "how" -> Set("ho", "ow"), "cho" -> Set("ho"), "cow" -> Set("ow")), List("chow", "how"))
println(b)
输出结果为:
List(List(chow, how, ho), List(chow, how, ow), List(chow, cho, ho), List(chow, cow, ow))
List(List(chow, how, ho), List(chow, how, ow), List(chow, cho, ho), List(chow, cow, ow), List(how, ho), List(how, ow))