2016-11-04 14 views
0

私は各ノードのノードスコアを得るための計算を実装しました。スカラ - 再帰的メソッドは異なる値を返します

値を得るための式は:

  • 子供リストが空でないか、またはフラグが真でなければなりません。

反復方法はかなりうまく機能:

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

そして、ここでは、私は結果を確認するために実行している部分です。

ありがとうございます。

答えて

2

再帰バージョンは、ノードの子に対して、末尾だけで再帰することはありません。反復バージョンは、子どもの上で正しく再帰し、尾を反復します。

"反復"バージョンも再帰的なbtwであることがわかります。

+0

しかし、どうすれば修正できますか?再帰バージョンをn.tailの代わりにn.head.childrenを使用するように変更しましたが、まだ動作していません。 – placplacboom

+0

おそらく 'score + scoreRec(n.tail、score + scala.math.pow(0.5、depth)、depth)+ scoreRec(n.children、score + scala.math.pow(0.5、depth + 1)、深さ+1) '私は思いますか? – C4stor

+0

いいえ、すでに試してみました。正しい値は3.375で、私がそのようにすれば26.8125を返します。 – placplacboom

関連する問題