[英]How do I sum all the elements from the leaf to the root of each branch in a n-ary tree in OCaml?
[英]How do I check if there is a child at an n position in a n-ary tree in OCaml?
我正在嘗試創建一個函數,給定一個元組列表(我不知道元組是否是正確的術語,我的意思是一個(x,y)列表)和一個 n 叉樹,它返回葉子檢查元組中的鍵是否存在於樹中,並將子項置於與該鍵關聯的值的位置,如果它不存在,則會引發錯誤。
我知道我沒有很好地解釋它,所以我會舉一個例子來幫助自己。 tuple list = [(1,3);(2,2);(3,1);(10,1)] 如果根的值為 1,那么它將檢查第三個孩子(如果不是,它將繼續列表),那么如果孩子的值為 10,它將檢查他的第一個孩子,直到找到葉子為止。
我想做的是首先使用 List.map 刪除與元組的鍵不匹配的元素以及不在關聯值的值位置的子元素,然后遞歸地對其子元素執行相同的操作。
這是我所做的:
type 'a ntree = Tr of 'a * 'a ntree list;;
let leaf x = Tr(x,[]);;
let alb = Tr(1,[Tr(2,[leaf 3; leaf 4; leaf 2]);Tr(5,[leaf 11; leaf 10]);Tr(3,[leaf 9; leaf 7; leaf 10])]);;
let guida = [(1,3);(2,2);(3,1);(10,1);(16,2);(11,2)];;
let rec cerca_foglia guida (Tr(x,tlist)) =
match tlist with
[] -> x
|_ -> List.map(fun a -> List.mem_assoc x guida && (*a.position = List.nth tlist List.assoc x guida*)) (cerca tlist)
and cerca = function
[] -> raise NotFound
|[t] -> cerca_foglia guida t
|t::rest ->
try cerca_foglia guida t
with NotFound -> cerca rest
經過深思熟慮,我想我可能已經明白了一些。 我寫了兩個函數: find_child
和find_child2
。
type 'a ntree = Tr of 'a * 'a ntree list
let leaf x = Tr(x,[])
let alb = Tr(1,[Tr(2,[leaf 3; leaf 4; leaf 2]);Tr(5,[leaf 11; leaf 10]);Tr(3,[leaf 9; leaf 7; leaf 10])])
let guida = [(1,3);(2,2);(3,1);(10,1);(16,2);(11,2)]
let rec find_child (Tr (root, children) as tree) =
function
| [] -> None
| (k, v)::_ when root = k -> Some (List.nth children (v - 1))
| _::kvs -> find_child tree kvs
let rec find_child2 (Tr (root, children) as tree) key_val_list =
match children with
| [] -> Some tree
| _ ->
(match key_val_list with
| [] -> None
| (k, v)::kvs when root = k -> find_child2 (List.nth children (v - 1)) kvs
| _::kvs -> find_child2 tree kvs)
find_child
函數在找到的第一個匹配項處停止。 所以評估find_child alb guida
產量:
utop # find_child alb guida;;
- : int ntree option = Some (Tr (3, [Tr (9, []); Tr (7, []); Tr (10, [])]))
find_child2
函數做了類似的事情,但它只在找到“葉子”或在當前節點中找不到它正在尋找的任何鍵時才停止。
utop # find_child2 alb guida;;
- : int ntree option = Some (Tr (9, []))
並稍微重構find_child2
以清理它並處理可能發生的Failure "nth"
異常:
let rec find_child3 (Tr (root, children) as tree) key_val_list =
match children, key_val_list with
| [], _ -> Some tree
| _, [] -> None
| _, (k, v)::kvs when root = k ->
(match List.nth children (v - 1) with
| child -> find_child3 child kvs
| exception (Failure "nth") -> None)
| _, _::kvs -> find_child3 tree kvs
| exception Failure "nth" -> None
當我們評估find_child3 alb guida
時,勾勒出遞歸的樣子:
find_child3 alb guida
find_child3 (Tr(1,
[Tr(2,[leaf 3; leaf 4; leaf 2]);
Tr(5,[leaf 11; leaf 10]);
Tr(3,[leaf 9; leaf 7; leaf 10])]))
[(1,3);(2,2);(3,1);(10,1);(16,2);(11,2)]
find_child3 (Tr(3,[leaf 9; leaf 7; leaf 10]))
[(2,2);(3,1);(10,1);(16,2);(11,2)]
find_child3 (Tr(3,[leaf 9; leaf 7; leaf 10]))
[(3,1);(10,1);(16,2);(11,2)]
find_child3 (leaf 9) [(10,1);(16,2);(11,2)]
Some (Tr (9, []))
這是你要找的東西嗎?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.