Scala - 递归方法返回不同的值

时间:2016-11-04 15:57:35

标签: scala recursion

我已实施计算以获取每个节点的节点分数。

获取值的公式为:

  • 子列表不能为空或标志必须为true;

迭代方式非常有效:

class TreeManager {

def scoreNo(nodes:List[Node]): List[(String, Double)] = {
  nodes.headOption.map(node => {
    val ranking = node.key.toString -> scoreNode(Some(node)) :: scoreNo(nodes.tail)
    ranking ::: scoreNo(node.children)
  }).getOrElse(Nil)
}

def scoreNode(node:Option[Node], score:Double = 0, depth:Int = 0):Double = {
  node.map(n => {
    var nodeScore = score
    for(child <- n.children){
      if(!child.children.isEmpty || child.hasInvitedSomeone == Some(true)){
        nodeScore = scoreNode(Some(child), (nodeScore + scala.math.pow(0.5, depth)), depth+1)
      }
    }
    nodeScore
  }).getOrElse(score)
}
}

但在我重构这段代码以使用递归之后,结果完全错了:

class TreeManager {

def scoreRecursive(nodes:List[Node]): List[(Int, Double)] = {

  def scoreRec(nodes:List[Node], score:Double = 0, depth:Int = 0): Double = nodes match {
    case Nil => score
    case n =>
      if(!n.head.children.isEmpty || n.head.hasInvitedSomeone == Some(true)){
        score + scoreRec(n.tail, score + scala.math.pow(0.5, depth), depth + 1)
      } else {
        score
      }
  }
  nodes.headOption.map(node => {
    val ranking = node.key -> scoreRec(node.children) :: scoreRecursive(nodes.tail)
    ranking ::: scoreRecursive(node.children)
  }).getOrElse(Nil).sortWith(_._2 > _._2)

}
}

Node是树的对象,它由以下类表示:

case class Node(key:Int,
                children:List[Node] = Nil,
                hasInvitedSomeone:Option[Boolean] = Some(false))

以下是我正在检查结果的部分:

object Main {
  def main(bla:Array[String]) = {

    val xx = new TreeManager

    val values = List(
      Node(10, List(Node(11, List(Node(13))),
        Node(12,
          List(
            Node(14, List(
              Node(15, List(Node(18))), Node(17, hasInvitedSomeone = Some(true)),
                Node(16, List(Node(19, List(Node(20)))), 
                  hasInvitedSomeone = Some(true))),
              hasInvitedSomeone = Some(true))),
          hasInvitedSomeone = Some(true))),
      hasInvitedSomeone = Some(true)))


    val resIterative = xx.scoreNo(values)
    //val resRecursive = xx.scoreRec(values)

    println("a")
  }
}

迭代方式正在运行,因为我已经检查了它,但我不明白为什么递归返回错误的值。

有什么想法吗?

提前感谢。

1 个答案:

答案 0 :(得分:2)

递归版本永远不会对节点的子节点进行递归,只是在尾部。而迭代版本正确地对儿童进行递归并迭代尾部。

你会注意到你的&#34;迭代&#34;版本也是递归btw。