【问题标题】:F# searching in trees F#F# 在树中搜索 F#
【发布时间】:2015-01-26 07:22:29
【问题描述】:

在递归树类型中找到一个'item/object/type',树类型是UNSORTED,因此二分查找操作不会成功。

Type Tree = T of (Name*Children)
And Children = Tree list
//findTree :Tree*Name -> Tree

我的代码(不起作用)

let rec findTree t n = List.find(fun (T(nameTree,childTree)) -> n=nameTree ) t

我尝试过使用递归和辅助函数,但结果非常混乱,没有成功。

【问题讨论】:

  • 这是用 [haskell] 标记的,因为您也在寻找 Haskell 实现吗?
  • 如果你有,那么请,或者只是功能性伪代码 :) 我的教授告诉我 F# 是微软版本的 haskall,所以我认为相似度很高。(如反对面向对象)
  • 所以我承认我对 F# 不是很熟悉,我是一个 Haskell 人,所以这种类型是否等同于类型data Tree = T Name [Tree](本质上是一个rose tree)?
  • 看起来很接近,一棵有 0..n 个子节点的树是无序的

标签: recursion tree f# functional-programming


【解决方案1】:

您的基本类型本质上是这样的(清理了缺失的类型):

type Tree = 
    | Tree of (string * Tree list)

现在树是未排序的,所以你能做的最好的就是线性搜索,递归地沿着子节点向下直到找到匹配。在以下情况下,搜索是深度优先的:

[<CompilationRepresentationAttribute(CompilationRepresentationFlags.ModuleSuffix)>]
module Tree = 
    let find p tree = 
        let rec findInner t =
            match t with
            | Tree(n, _) when p(n) -> Some(t)
            | Tree(_, children) -> children |> Seq.choose (findInner) 
                                            |> Seq.tryFind (fun _ -> true)
            | Tree(_, []) -> None
        findInner tree

如果需要,您可以使用List.chooseList.tryFind,我使用了Seq,所以它会在tryFind 上提前停止。 此外,此版本在名称上有谓词匹配。如果您总是想使用相等,您可以添加名称作为参数并将p 替换为namewhen p(n)when n = name

现在,做一个小测试:

let tree = Tree("A", 
                [Tree("B", 
                    [Tree("C",[]); 
                     Tree("D", 
                        [Tree("E",[])])
                    ]); 
                Tree("F",[])
                ])

tree |> Tree.find (fun n -> n = "B") |> printfn "%A"
tree |> Tree.find (fun n -> n = "D") |> printfn "%A"
tree |> Tree.find (fun n -> n = "E") |> printfn "%A"
tree |> Tree.find (fun n -> n = "TEST") |> printfn "%A"
tree |> Tree.find (fun n -> n = "F") |> printfn "%A"

分别打印哪些:

Some (Tree ("B", [Tree ("C", []); Tree ("D", [Tree ("E", [])])]))
Some (Tree ("D", [Tree ("E", [])]))
Some (Tree ("E", []))
<null>
Some (Tree ("F", []))

【讨论】:

  • 能否请您详细说明您如何使用 Seq/List.choose(function) |> Seq/List.tryFind (fun _ -> true) ??
  • @user3711518 应用选择器'T-&gt;'U option 以获得过滤后的 映射序列,并将其第一个元素返回为'U option。可以替换为Seq.tryPick
  • @kaefer 没错,我完全忘记了tryPick :)
猜你喜欢
  • 1970-01-01
  • 2019-04-12
  • 2018-05-12
  • 1970-01-01
  • 2020-06-21
  • 2018-08-05
  • 2015-12-24
  • 2016-01-30
相关资源
最近更新 更多