solution de Nyavro peut être beaucoup plus rapide (de plusieurs ordres de grandeur) si vous utilisez des listes au lieu des cours d'eau et ajouter également des éléments à l'avant. Cela est dû au fait que x.children est généralement beaucoup plus court que xs et que la liste de Scala est une liste unidirectionnelle immuable qui rend les opérations d'avance beaucoup plus rapides que les opérations d'ajout. Voici un exemple
import scala.annotation.tailrec
case class Category(name:String, children: List[Category])
@tailrec
def childCount(cats:Stream[Category], acc:Int):Int =
cats match {
case Stream.Empty => acc
case x #:: xs => childCount(xs ++ x.children, acc+1)
}
@tailrec
def childCount2(cats: List[Category], acc:Int): Int =
cats match {
case Nil => acc
case x :: xs => childCount2(x.children ++ xs, acc + 1)
}
def generate(depth: Int, children: Int): List[Category] = {
if(depth == 0) Nil
else (0 until children).map(i => Category("abc", generate(depth - 1, children))).toList
}
val list = generate(8, 3)
var start = System.nanoTime
var count = childCount(list.toStream, 0)
var end = System.nanoTime
println("count: " + count)
println("time: " + ((end - start)/1e6) + "ms")
start = System.nanoTime
count = childCount2(list, 0)
end = System.nanoTime
println("count: " + count)
println("time: " + ((end - start)/1e6) + "ms")
sortie:
count: 9840
time: 2226.761485ms
count: 9840
time: 3.90171ms
Qu'avez-vous essayé? Quel est votre problème concernant la fonction récursive de la queue? – marstran
Rendre la queue récursive pourrait être difficile puisque vous traversez une arborescence comme la structure de données. Fondamentalement, la seule façon de le faire est de garder une liste de tout le travail à faire (par exemple, être de type List [catégorie] qui serait alors utilisé comme une pile) et en faire un argument pour la fonction. – SpiderPig
@SpiderPig Vous avez seulement besoin d'un accumulateur qui contient le nombre actuel. – marstran