我敢肯定有一個漂亮的方式(有見布賴恩的答案是更好!):
(defn find-in-trie
"Finds a sub trie that matches an item, eg:
user=> (find-in-trie '(1 (2) (3 (2))) 3)
(3 (2))"
[tr item]
(first (for [ll (rest tr) :when (= (first ll) item)] ll)))
(defn add-to-trie
"Returns a new trie, the result of adding se to tr, eg:
user=> (add-to-trie nil '(1 2))
(1 (2))"
[tr se]
(cond
(empty? se) tr
(empty? tr) (add-to-trie (list (first se)) (rest se))
:else (if-let [st (find-in-trie tr (first se))]
(cons (first tr)
(cons (add-to-trie st (rest se))
(filter (partial not= st) (rest tr))))
(cons (first tr)
(cons (add-to-trie (list (first se)) (rest se))
(rest tr))))))
(def in '((1 2)
(1 2 3)
(1 2 4 5 9)
(1 2 4 10 15)
(1 2 4 20 25)))
(reduce add-to-trie '(nil) in)
- >(NIL(1(2(4(20(25))(10 (15))(5(9)))(3))))
請注意,我選擇使用nil作爲根節點,並且沒有打擾空列表來表示沒有孩子。實際上這樣做是不正確的,因爲它不保留子字符串的身份。
所以Brian的版本會很好我猜如果你總是使用相同數量的鍵? – Johnny 2010-04-14 04:20:38
您對prefix-matches的定義使用函數map-filter,但標準庫中沒有這樣的函數。我試圖反向工程,但它並不明顯。你可以發佈它的定義嗎? – 2015-01-17 04:34:25
'map-filter'類似於'keep',它在覈心庫中。 – NielsK 2016-04-25 15:48:35