如何在Scala中列出通过DAG的路径

时间:2015-08-31 05:37:42

标签: scala tree

我有以下类型的单词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))

我无法弄明白为什么。我确信这很简单,但我现在就错过了它。

2 个答案:

答案 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))