編輯2:這整個問題和探索都是基於我錯過了拉鍊的基本概念;從特定節點的角度來看,它們代表了數據結構中的角度。因此,拉鍊始終是一對當前節點,並且從該節點的角度看,樹的其餘部分是什麼樣子。我最初試圖從拉鍊生成一個全新的結構,而拉鍊本身就是我所需要的,一直以來。我會把這一切都留給子孫後代,希望別人能夠得到幫助(或者這對任何接班人都是一種警告!)。Clojure拉鍊路徑功能不完整?
原題:
我試圖讓我的頭周圍採用拉鍊操縱樹。具體問題是我需要在運行時生成任意樹中符合任意條件的兩個節點之間的路由。
我以爲我可以使用path
函數通過在當前位置調用path
來獲取到某個位置的路由。但是,返回的路徑似乎忽略了達到目標所需的最後一步。
例如:
(def test-zip (vector-zip [0 [1] [2 [3 [4] 5 [6 [7] [8]]]]]))
(-> test-zip
down right right down
right down right right
node)
給人5
,但
(-> test-zip
down right right down
right down right right
path)
給
[[0 [1] [2 [3 [4] 5 [6 [7] [8]]]]] [2 [3 [4] 5 [6 [7] [8]]]] [3 [4] 5 [6 [7] [8]]]]
這是不相同的位置(這是錯過了最後三個步驟的效果,down right right
)。
它看起來像路徑函數只會讓你到樹中的父位置,忽略你和實際位置之間的任何兄弟姐妹。
我錯過了path
函數的要點嗎?我假設給定一棵樹和一條路徑,將路徑應用到樹會將您帶到路徑的原始位置,而不是部分路徑。
更新:我用下面的函數定義編譯結束位置,從起始位置的節點的路徑:
(defn lca-path [start-loc end-loc]
(let [sczip (z/root start-loc)
start-path (z/path start-loc)
start-node (z/node start-loc)
end-path (z/path end-loc)
end-node (z/node end-loc)
lca-path (filter (set start-path) end-path)
lca-node [(last lca-path)]
lca-to-start (conj (vec (drop (count lca-path) start-path)) start-node)
lca-to-end (conj (vec (drop (count lca-path) end-path)) end-node)
]
(concat (reverse lca-to-start) lca-node lca-to-end))
)
漂亮深受聊天與@馬克費舍爾的影響,謝謝!
因此,一旦你到達父子樹,你必須在最後一個子樹的直接子孫後面手動搜索所需的節點?假設立即下降的節點是「3」。 '[4]','5'和'[6 [7] [8]]'在這種情況下搜索範圍並不太大。但是,對於所有四個位置都返回相同的路徑,這並不奇怪嗎?有沒有其他一些慣用的方法來捕捉路線到拉鍊我失蹤的位置? –
我很高興與你分享這一次的旅程。我已經更新了我的答案,在2點之間包含一個查找器。這是否符合你想要實現的目標? –
另外我認爲這是因爲你使用簡單的矢量拉鍊,而不是一些自定義的拉鍊來覆蓋你的數據。 –