當我的腦袋疼的Cuz它粘在樹上,我儘量說些什麼我想爲簡單明瞭,我可以:
- 鑑於信息的樹,列出所有子樹匹配謂詞(在這種情況下,info = 3)。
一個簡單的方法就是列出樹的所有節點,然後過濾謂詞。
type 'info tree = Node of 'info * 'info tree list
let rec visit = function
| Node(info, []) as node -> [ node ]
| Node(info, children) as node -> node :: List.collect visit children
let filter predicate tree =
visit tree
|> List.filter (fun (Node(info,_)) -> predicate info)
這裏的樹過濾器對OP的樣本數據運行:
let test2 =
Node(("One",
[Node("Two",
[Node("Three",[Node("Five",[]);Node("Three",[])]);
Node("Three",[])]);
Node("Three",[])]))
let res2 = filter (fun info -> info = "Three") test2
:
令我驚訝的是代碼如何輕鬆地適用於任何「信息類型與相應的判定
let result = filter (fun info -> info = 3) test
一件事
或者,如果您想列出信息而不是子樹,代碼很簡單:
let rec visit = function
| Node(info, []) -> [ info ]
| Node(info, children) -> info :: List.collect visit children
let filter predicate tree =
visit tree
|> List.filter predicate
支持相同的查詢,但只返回「信息記錄,而不是樹形結構:
let result = filter (fun info -> info = 3) test
> val result : int list = [3; 3; 3; 3]
這些都不是尾遞歸。 – gradbot 2010-05-12 00:26:29
@gradbot:不,他們故意沒有。我認爲首先理解簡單版本是個好主意(在這種情況下,尾遞歸版本需要延續)。而且,O(log n)高度通常可以在沒有尾遞歸的情況下處理(假定樹是合理的)。 – 2010-05-12 00:29:16
@gradbot:...但指出這一事實絕對有用。 – 2010-05-12 00:33:36