J'essaie de trouver une fonction de pli récursif de queue pour un arbre binaire. Étant donné les définitions suivantes:Pli de queue récursif sur un arbre binaire dans Scala
// From the book "Functional Programming in Scala", page 45
sealed trait Tree[+A]
case class Leaf[A](value: A) extends Tree[A]
case class Branch[A](left: Tree[A], right: Tree[A]) extends Tree[A]
mise en œuvre d'une fonction récursive non la queue est assez simple:
def fold[A, B](t: Tree[A])(map: A => B)(red: (B, B) => B): B =
t match {
case Leaf(v) => map(v)
case Branch(l, r) =>
red(fold(l)(map)(red), fold(r)(map)(red))
}
Mais maintenant, je me bats pour trouver une fonction de rabattement récursive de la queue de sorte que l'annotation @annotation.tailrec
peut être utilisé.
Au cours de ma recherche, j'ai trouvé plusieurs exemples où les fonctions récursives de la queue sur un arbre peuvent, par exemple, calculer la somme de toutes les feuilles en utilisant une propre pile qui est alors fondamentalement un List[Tree[Int]]
. Mais dans la mesure où je comprends dans ce cas, cela ne fonctionne que pour les ajouts car il n'est pas important que vous évaluiez d'abord le côté gauche ou le côté droit de l'opérateur. Mais pour un pli généralisé, c'est tout à fait pertinent. Pour montrer mon intension voici quelques exemples des arbres:
val leafs = Branch(Leaf(1), Leaf(2))
val left = Branch(Branch(Leaf(1), Leaf(2)), Leaf(3))
val right = Branch(Leaf(1), Branch(Leaf(2), Leaf(3)))
val bal = Branch(Branch(Leaf(1), Leaf(2)), Branch(Leaf(3), Leaf(4)))
val cmb = Branch(right, Branch(bal, Branch(leafs, left)))
val trees = List(leafs, left, right, bal, cmb)
Sur la base de ces arbres, je veux créer une copie en profondeur avec la méthode de pliage donnée comme:
val oldNewPairs =
trees.map(t => (t, fold(t)(Leaf(_): Tree[Int])(Branch(_, _))))
Et la preuve que la condition de l'égalité est valable pour toutes les copies créées:
val conditionHolds = oldNewPairs.forall(p => {
if (p._1 == p._2) true
else {
println(s"Original:\n${p._1}\nNew:\n${p._2}")
false
}
})
println("Condition holds: " + conditionHolds)
Quelqu'un pourrait-il me donner des indications?
Vous pouvez trouver le code utilisé dans cette question à ScalaFiddle: https://scalafiddle.io/sf/eSKJyp2/15
Votre programme ne se termine pas des exemples dans ScalaFiddle. Et j'obtiens l'erreur java.lang.OutOfMemoryError: Java heap space' lorsque j'essaie de lancer ceci dans Ammonite pour 'leafs'. – adamwy
@adamwy Vous avez raison, il y avait une faute de frappe dans le cas 'Branch' pour lequel la pile n'était pas consommée. J'ai édité la réponse –
Maintenant je reçois ceci dans ScalaFiddle: 'Original: Branche (Feuille (1), Branche (Feuille (2), Feuille (3))) Nouveau: Branche (Branche (Feuille (1), Feuille (2)), Leaf (3)) La condition est la suivante: false' – adamwy