はじめを反復ツリー
次の関数は、反復的にネストされたベクトルで作られたツリー構造をトラバースからトライを構築します。それは述語に対して各リーフをテストします。その真理テストに合格したすべての葉への道はTrie structureに返されます。後では、見つけられたすべてのパスが重複しない方法で記述されます。
(defn get-trie-of-matches [is? tree]
(loop [[tree i path fk] [tree 0 [] nil]
accum {}]
(cond
(>= i (count tree)) ;; end of level/go up
(if (nil? fk) accum (recur fk accum))
(vector? (tree i)) ;; level down
(recur [(tree i) 0 (conj path i) [tree (inc i) path fk]] accum)
(is? (tree i)) ;; match
(let [new-accum (assoc-in accum (conj path i) {})]
(recur [tree (inc i) path fk] new-accum))
:else ;; next on same level
(recur [tree (inc i) path fk] accum))))
さらに詳しい説明は、this postを参照してください。
例
述語としてeven?
を使用して、関数に適用下記ツリー
(def tree [7 9 [7 5 3 [4 6 9] 9 3] 1 [2 7 9 9]])
を検討:
(get-trie-of-matches even? tree)
=> {2 {3 {0 {}, 1 {}}}, 4 {0 {}}}
結果が偶数にするために3つの経路を記述しtree
。即ち、2-3-0
,2-3-1
及び4-0
である。
問題
上記の機能が動作しても、ツリーを横断しながら、トライを構築するためのより良い方法があるかもしれません。現時点では、ハッシュマップがフラッディングされます。 assoc-inを介して各試合で。このアルゴリズムは、ツリー構造をレベルごとに相対的に横断しますが、各パスをグローバルな方法でaccum
に接続しますが、これは必須ではありません。また、このメソッドはハッシュマップが使用されるためのみ可能です。それ以上の反復を容易にするために、Trieのシーケンシャルなデータ構造を使用する方がよいでしょう。これは上記の方法には適用できませんでした。トライは、ハッシュマップ固有の「グローバル」「書き込み」の機能に依存することなく、上記の関数get-trie-of-matches
内から作成することができますどのように
質問
?
:実際には、あなたは、例えば機能に若干の変更、マップの構造をしたい任意の構造を生成することができますprogramming-in-clojurescript-with-sp.html)を参照してください。これにより、データ構造をどのように配置したいかを指定することができます。これは、プログラミングの容易さと同様に、高性能(「ゲットイン」よりも優れている)との両方を提供すると主張している。 –
あなたはあなたが提供した実装であなたの問題が何であるかに関してもっと具体的になりますか?確かに同じことを達成する "より良い"方法がありますが、何が違うべきかははっきりしていません。たとえば、「hasp-map特有のグローバルな「書き込み」関数」という意味ですか?あなたは怠惰な解決策を探していますか? –