如何使函数返回浮动列表?

时间:2018-11-11 15:33:03

标签: f# f#-interactive f#-data f#-3.0 f#-fake

请问,如何使此函数返回每个分支和叶子的值作为浮动列表?我已经尝试了几种使用Tail递归的方法,但是我无法返回无法遍历分支和叶子的头部。

type 'a Tree =   | Leaf   of 'a   | Branch of 'a Tree * 'a Tree

let medianInTree (lst: float Tree) :float list=
    let rec medianInTree' (a : float Tree) acc = 
        match lst with
        | Leaf(n) -> n :: acc
        | Branch(Leaf(xx), Leaf(xs)) -> xx :: [xs] 
        | Branch(Leaf(x), Branch(Leaf(xx), Leaf(xs))) -> 
               let acc = medianInTree'(Leaf(x)) acc
               medianInTree' (Branch(Leaf(xx), Leaf(xs))) acc 
        | Branch(_, _) -> []
    medianInTree' lst []

问题:medianInTree (Branch(Leaf(2.0), Branch(Leaf(3.0), Leaf(5.0))))

我想要这个结果:[2.0; 3.0; 5.0]

2 个答案:

答案 0 :(得分:2)

使用累加器,您可以执行以下操作:

let flatten tree =
    let rec toList tree acc =
        match tree with
        | Leaf a -> a :: acc
        | Branch(left, right) ->
            let acc = toList left acc
            toList right acc
    toList tree [] |> List.rev

但是这样做,处理左分支的递归调用不是尾递归。 为了确保在处理树结构时尾部递归,您必须使用continuations

let flatten tree = 
    let rec toList tree cont acc =
        match tree with
        | Leaf a              -> cont (a :: acc)
        | Branch(left, right) -> toList left (fun l ->
                                    toList right (fun r -> 
                                        cont r) (cont l)) acc
    toList tree id [] |> List.rev

可以简化为:

let flatten tree = 
    let rec toList tree cont acc =
        match tree with 
        | Leaf a               -> cont (a :: acc)
        | Branch (left, right) -> toList left (toList right cont) acc
    toList tree id [] |> List.rev

答案 1 :(得分:1)

您的主要错误是将matchlst一起使用,而不是在a上使用。我也简化了。

let medianInTree (lst: float Tree) :float list=
    let rec medianInTree' (a : float Tree)= 
        match a with
        | Leaf(n) -> [n]
        | Branch(l, r) -> (medianInTree' l) @ (medianInTree' r)
    medianInTree' lst