2016-11-04 5 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

재귀 버전은 절대로 꼬리 부분에있는 노드의 하위 노드에서 재귀되지 않습니다. 반복적 인 버전은 어린이들에게 반복적으로 반복되고 꼬리를 반복합니다.

"반복적 인"버전도 재귀적임을 알 수 있습니다.

+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

관련 문제