【问题标题】:Scala - Recursive method is return different valuesScala - 递归方法返回不同的值
【发布时间】:2016-11-04 15:57:34
【问题描述】:

我已经实现了一个计算来获得每个节点的节点分数。

取值公式为:

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

迭代方式效果很好:

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)

}
}

节点是树的一个对象,它由以下类表示:

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")
  }
}

迭代方式有效,因为我已经检查过了,但我不明白为什么递归返回错误值。

有什么想法吗?

提前致谢。

【问题讨论】:

    标签: scala recursion


    【解决方案1】:

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

    你会注意到你的“迭代”版本也是递归的。

    【讨论】:

    • 但是我该如何解决呢?我已将递归版本更改为使用 n.head.children 而不是 n.tail 但仍然无法正常工作。
    • 我想应该是score + scoreRec(n.tail, score + scala.math.pow(0.5, depth), depth) + scoreRec(n.children, score + scala.math.pow(0.5, depth+1), depth+1)
    • 不,已经试过了。正确的值是 3.375,如果我这样做,它会返回 26.8125。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-27
    • 2020-08-31
    • 2016-08-03
    • 1970-01-01
    • 1970-01-01
    • 2018-09-18
    相关资源
    最近更新 更多