簡體   English   中英

OCaml 將函數數組作為二叉樹轉換為列表

[英]OCaml converting functional arrays as binary tree to list

我必須將函數數組轉換為 OCaml 上的列表,這是我到目前為止所擁有的,但它沒有通過測試,任何人都可以幫助解決我的代碼有什么問題以及我應該使用什么方法?

我首先編寫了一個函數來返回除第一個值之外的樹,然后將其頭部和其余部分的頭部相結合以創建一個列表。 我做錯了嗎?

exception Subscript

let top = function
  | Lf -> raise Subscript
  | Br (v,_,_) -> v

let rec pop = function
  | Lf -> raise Subscript
  | Br (_, Lf, Lf) -> Lf
  | Br (_, lt, rt) -> Br (top lt, rt, pop lt)

let rec listofarray = function
  | Br (v, t1, t2) -> v :: (listofarray (pop (Br(v, t1, t2))))
  | Lf -> []

你沒有說樹是否有額外的不變量。 除非對可能的樹有限制,否則您的pop函數不適用於所有樹:

# pop (Br (0, Br (1, Lf, Lf), Lf));;
- : tree = Br (1, Lf, Lf)
# pop (Br (0, Lf, Br (1, Lf, Lf)));;
Exception: Subscript.

正如 Jeffrey Scofield 所建議的那樣,您可能希望修改pop的實現以處理左樹或右 tee 是Lf但不是兩者的情況

let rec pop = function
  | Lf -> raise Subscript
  | Br (_, Lf, Lf) -> Lf
  | Br (_, Lf, rt) -> ...
  | Br (_, lt, Lf) -> ...
  | Br (_, lt, rt) -> Br (top lt, rt, pop lt)

現在的問題是pop在每種情況下應該做什么。 考慮第一種情況。

   0
  / \
 /   \
Lf    1
     / \
    /   \
   Lf   Lf

很明顯,在pop之后我們應該有:

   1
  / \
 /   \
Lf   Lf

我們可以通過簡單地返回正確的樹來獲得它。

let rec pop = function
  | Lf -> raise Subscript
  | Br (_, Lf, Lf) -> Lf
  | Br (_, Lf, rt) -> rt
  | Br (_, lt, Lf) -> ...
  | Br (_, lt, rt) -> Br (top lt, rt, pop lt)

同樣,如果我們考慮另一種情況,我們可以看到解決方案同樣簡單。

         0              1
        / \            / \ 
       /   \          /   \
      1    Lf   ->   Lf   Lf
     / \
    /   \
   Lf   Lf

我們可以通過返回左樹來實現這一點。

let rec pop = function
  | Lf -> raise Subscript
  | Br (_, Lf, Lf) -> Lf
  | Br (_, Lf, rt) -> rt
  | Br (_, lt, Lf) -> lt
  | Br (_, lt, rt) -> Br (top lt, rt, pop lt)

現在,在不更改listofarray我們在評估 Jeffrey Scofield 提供的示例時確實得到了正確的結果。

utop # listofarray (Br (0, Lf, Br (1, Lf, Lf)));;
- : int list = [0; 1]
utop # listofarray (Br (0, Br (1, Lf, Lf), Lf));;
- : int list = [0; 1]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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