簡體   English   中英

如何檢查OCaml中n叉樹的n位置是否有孩子?

[英]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_childfind_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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM