Fauler Druck eines Baumes im Newick-Format

Ich möchte einen binären Baum in druckenNewick-FormatZeigt die Entfernung jedes Knotens zu seinem Elternknoten an. Im Moment habe ich kein Problem mit dem folgenden Code gehabt, der eine regelmäßige Rekursion verwendet, aber ein zu tiefer Baum kann einen Stapelüberlauf erzeugen.

(defn tree->newick
  [tree]
  (let [{:keys [id children to-parent]} tree
        dist (double to-parent)] ; to-parent may be a rational
    (if children
      (str "(" (tree->newick (first children)) 
           "," (tree->newick (second children)) 
           "):" dist)
      (str (name id) ":" dist))))

(def example {:id nil :to-parent 0.0 
              :children [{:id nil :to-parent 0.5 
                          :children [{:id "A" :to-parent 0.3 :children nil}
                                     {:id "B" :to-parent 0.2 :children nil}]}
                         {:id "C" :to-parent 0.8 :children nil}]})

(tree->newick example)
;=> "((A:0.3,B:0.2):0.5,C:0.8):0.0"

(def linear-tree (->> {:id "bottom" :to-parent 0.1 :children nil}
                   (iterate #(hash-map :id nil :to-parent 0.1 
                                       :children [% {:id "side" :to-parent 0.1 :children nil}]))
                   (take 10000)
                   last))

(tree->newick linear-tree)
;=> StackOverflowError

Das Problem habe ich mit aktuellen Dienstprogrammen gefunden, wie ztree-seq undclojure.walk, ist, dass ich mehr als einmal einen inneren Knoten aufsuchen muss, um das Komma einzufügen und die Klammer zu schließen. Ich habe benutztclojure.zip, aber es ist mir nicht gelungen, eine Lazy / Tail-rekursive Implementierung zu schreiben, da ich für jeden inneren Knoten speichern müsste, wie oft sie bereits besucht wurden.

Antworten auf die Frage(1)

Ihre Antwort auf die Frage