首页 \ 问答 \ 使用F#实现树构建器(Implement tree builder with F#)

使用F#实现树构建器(Implement tree builder with F#)

我是F#的新手,我想实现以下问题的解决方案:从随机顺序发现的一系列磁盘路径(例如“C:\ Hello \ foo”“C:”,“C:\ Hello \ bar “等......)如何构建(有效)树。 假设:序列有效,这意味着可以有效地创建树。

所以我尝试使用递归函数(下面的“mergeInto”)实现,该函数将树“就地”与字符串列表(称为“branch”的分割路径)合并在一起

这是我的实现,不变性防止了对输入树的副作用,所以我尝试使用ref单元格作为输入树,但我遇到了递归的困难。 有解决方案吗

open Microsoft.VisualStudio.TestTools.UnitTesting

type Tree =
    |Node of string*list<Tree>
    |Empty

let rec branchToTree (inputList:list<string>) =
    match inputList with
        | [] -> Tree.Empty
        | head::tail ->  Tree.Node (head, [branchToTree tail])

//branch cannot be empty list
let rec mergeInto (tree:Tree ref) (branch:list<string>) =
    match !tree,branch with
        | Node (value,_), head::tail when String.op_Inequality(value, head) -> raise (ApplicationException("Oops invariant loop broken"))
        | Node (value,_), [_] -> ignore() //the branch is singleton and by loop invariant its head is the current Tree node -> nothing to do.
        | Node (value,children), _ -> 
                                let nextBranchValue = branch.Tail.Head //valid because of previous match

                                //broken attempt to retrieve a ref to the proper child
                                let targetChild = children 
                                                |> List.map (fun(child) -> ref child)
                                                |> List.tryFind (fun(child) -> match !child with
                                                                                        |Empty -> false
                                                                                        |Node (value,_) -> value = nextBranchValue)
                                match targetChild with
                                    |Some x -> mergeInto x branch.Tail //a valid child match then go deeper. NB: branch.Tail cannot be empty here
                                    |None -> tree := Node(value, (Node (nextBranchValue,[])) :: children)//attach the next branch value to the children
        | Empty,_ -> tree := branchToTree branch

[<TestClass>]
type TreeTests () = 
    [<TestMethod>]
    member this.BuildTree () =
        let initialTree = ref Tree.Empty
        let branch1 = ["a";"b";"c"]
        let branch2 = ["a";"b";"d"]

        do mergeInto initialTree branch1
        //-> my tree is ok
        do mergeInto initialTree branch2
        //->not ok, expected a
        //                   |
        //                   b
        //                  / \
        //                 d   c 

I am pretty new to F# and I wanted to implement a solution to the following problem: From a sequence of disk paths discovered in random order (e.g. "C:\Hello\foo" "C:" , "C:\Hello\bar" etc....) how to build (efficiently) the tree. Assumption: the sequence is valid, which means the tree can be effectively created.

So I tried to implement with a recursive function ("mergeInto" in the following) which merges the tree "in place" with a list of string (the splitted path called "branch")

Here is my implementation, the immutability prevents side effects on the input tree, so I tried to use a ref cell for the input Tree but I encounter difficulty with the recursion. Any solution ?

open Microsoft.VisualStudio.TestTools.UnitTesting

type Tree =
    |Node of string*list<Tree>
    |Empty

let rec branchToTree (inputList:list<string>) =
    match inputList with
        | [] -> Tree.Empty
        | head::tail ->  Tree.Node (head, [branchToTree tail])

//branch cannot be empty list
let rec mergeInto (tree:Tree ref) (branch:list<string>) =
    match !tree,branch with
        | Node (value,_), head::tail when String.op_Inequality(value, head) -> raise (ApplicationException("Oops invariant loop broken"))
        | Node (value,_), [_] -> ignore() //the branch is singleton and by loop invariant its head is the current Tree node -> nothing to do.
        | Node (value,children), _ -> 
                                let nextBranchValue = branch.Tail.Head //valid because of previous match

                                //broken attempt to retrieve a ref to the proper child
                                let targetChild = children 
                                                |> List.map (fun(child) -> ref child)
                                                |> List.tryFind (fun(child) -> match !child with
                                                                                        |Empty -> false
                                                                                        |Node (value,_) -> value = nextBranchValue)
                                match targetChild with
                                    |Some x -> mergeInto x branch.Tail //a valid child match then go deeper. NB: branch.Tail cannot be empty here
                                    |None -> tree := Node(value, (Node (nextBranchValue,[])) :: children)//attach the next branch value to the children
        | Empty,_ -> tree := branchToTree branch

[<TestClass>]
type TreeTests () = 
    [<TestMethod>]
    member this.BuildTree () =
        let initialTree = ref Tree.Empty
        let branch1 = ["a";"b";"c"]
        let branch2 = ["a";"b";"d"]

        do mergeInto initialTree branch1
        //-> my tree is ok
        do mergeInto initialTree branch2
        //->not ok, expected a
        //                   |
        //                   b
        //                  / \
        //                 d   c 

原文:https://stackoverflow.com/questions/17364840
更新时间:2023-03-14 14:03

最满意答案

我认为beta减少可以指定单步和多步beta减少。

我可以说beta减少可以从(/x./y./zx) ab产生/za ,但我不能说单步β减少可以做到这一点。

你所说的其余部分是正确的。


I would think that beta reduction can designate both single and multi step beta reductions.

I can say that beta reduction can yield /z.a from (/x./y./z.x) a b, but I cannot say that a single step beta reduction can do that.

The rest of what you said is correct.

相关问答

更多
  • 我认为beta减少可以指定单步和多步beta减少。 我可以说beta减少可以从(/x./y./zx) ab产生/za ,但我不能说单步β减少可以做到这一点。 你所说的其余部分是正确的。 I would think that beta reduction can designate both single and multi step beta reductions. I can say that beta reduction can yield /z.a from (/x./y./z.x) a b, but ...
  • 我问我的TA,他说应用程序是关联的,意思是 (\kf.f(\c.co)km)(\x.dox)(\le.le) 相当于 ( [\kf.( [ f(\c.co) ]k )m ][\x.dox] )[ \le.le ] 这解释了为什么k不能应用于(\c.co) 。:/ 括号/括号仅用于使其更具可读性。 问候。 I asked my TA, he said that application is left associative, meaning (\kf.f(\c.co)km)(\x.dox)(\le.le) ...
  • 那么容易,那么我想: class Test: @staticmethod def mul(x,y): return x*y FUNC1 = staticmethod(lambda y: Test.mul(y,2)) FUNC2 = staticmethod(lambda y: lambda x: Test.mul(y,x)) print Test.FUNC1(2) print Test.FUNC2(2)(3) 这工作 well that was easier ...
  • 大概你想避免多次通过,因为管道阶段可能很昂贵。 或者您希望避免收集中间值以便通过多个收集器运行它们,因为存储所有值的成本可能太高。 正如Brian Goetz所指出的 , Collectors.summarizingInt将收集int值并对它们执行多次约简,返回一个名为IntSummaryStatistics的聚合结构。 有类似的收集器用于汇总double和long值。 不幸的是,它们只执行一组固定的减少,所以如果你想减少与它们不同的减少,你必须编写自己的收集器。 这是一种在一次通过中使用多个不相关的收集器 ...
  • 你可能想尝试像这样的cbv战术 : Definition foo := (fun (x : nat) => x) 42. Definition bar := (fun (x : nat) => x) 42. Goal foo = bar. cbv delta [foo]. 这导致以下证明状态: (fun x : nat => x) 42 = bar You might want to try e.g. the cbv tactic like so: Definition foo := (fun ( ...
  • Beta降低只是lambda演算中用于计算的主要应用规则。 它通过替换应用,如下所示: 如果你有lambda术语:(\ xx)和右边的一些值:y 然后,您将所有绑定变量替换为lambda术语中(。)的右侧。 绑定变量是与(。)左边的变量匹配的变量,因此在这种情况下为x。 The reduction would be of the form: (\x.x)y //y gets bound to all occurences of x to the right of the period y 其中y绑定 ...
  • SoX是一个跨平台的命令行应用程序,可以进行音频操作。 快速检查手册页显示它可以降噪(参见noiseprof和noisered )。 您可以将trim与noiseprof结合使用,选择较大音频文件的小片段作为噪音。 SoX is a cross-platform command-line application that does audio manipulation. A quick check of the man page reveals that it can do noise reduction ...
  • 每个样本需要一个单独的p ( shape参数是新的): with pm.Model() as model1: alpha1 = pm.Uniform('alpha', 1, 100) beta1 = pm.Uniform('beta', 1, 100) p1 = pm.Beta('prob', alpha=alpha1, beta=beta1, shape=1000) X1 = pm.Binomial('X1', n=n_data, p=p1, observed=x_data ...
  • 恢复步骤: Y = ƛf.( ƛx.f(xx)) ( ƛx.f(xx)) = ƛf.( f ( ƛx.f(xx) ƛx.f(xx) ) ) = ƛf.( f ( f (ƛx.f(xx) ƛx.f(xx)))) = ƛf.( f ( f ( f (ƛx.f(xx) ƛx.f(xx)))) = ƛf.( f ( f ( f ( f (ƛx.f(xx) ƛx.f(xx))))) = ... 所以这个Lambda术语进入无限循环...... 说明: 让我们看一下术语( ƛx.f(xx) ƛx.f ...
  • 减少是一种你可以用块做的操作。 最简单的解决方案是在GPU上分配两个数据缓冲区和两个结果缓冲区,然后通过执行缩减内核重叠传输到GPU。 当GPU忙时,您的CPU可以减少连续GPU减少的输出。 这样,您可以分摊大部分数据传输成本,并处理部分缩减结果。 您可以使用带有CUDA示例的标准缩减内核NVIDIA供应来完成所有这些工作。 Reduction is an operation which you can do in chunks. The simplest solution would be to allo ...

相关文章

更多

最新问答

更多
  • 获取MVC 4使用的DisplayMode后缀(Get the DisplayMode Suffix being used by MVC 4)
  • 如何通过引用返回对象?(How is returning an object by reference possible?)
  • 矩阵如何存储在内存中?(How are matrices stored in memory?)
  • 每个请求的Java新会话?(Java New Session For Each Request?)
  • css:浮动div中重叠的标题h1(css: overlapping headlines h1 in floated divs)
  • 无论图像如何,Caffe预测同一类(Caffe predicts same class regardless of image)
  • xcode语法颜色编码解释?(xcode syntax color coding explained?)
  • 在Access 2010 Runtime中使用Office 2000校对工具(Use Office 2000 proofing tools in Access 2010 Runtime)
  • 从单独的Web主机将图像传输到服务器上(Getting images onto server from separate web host)
  • 从旧版本复制文件并保留它们(旧/新版本)(Copy a file from old revision and keep both of them (old / new revision))
  • 西安哪有PLC可控制编程的培训
  • 在Entity Framework中选择基类(Select base class in Entity Framework)
  • 在Android中出现错误“数据集和渲染器应该不为null,并且应该具有相同数量的系列”(Error “Dataset and renderer should be not null and should have the same number of series” in Android)
  • 电脑二级VF有什么用
  • Datamapper Ruby如何添加Hook方法(Datamapper Ruby How to add Hook Method)
  • 金华英语角.
  • 手机软件如何制作
  • 用于Android webview中图像保存的上下文菜单(Context Menu for Image Saving in an Android webview)
  • 注意:未定义的偏移量:PHP(Notice: Undefined offset: PHP)
  • 如何读R中的大数据集[复制](How to read large dataset in R [duplicate])
  • Unity 5 Heighmap与地形宽度/地形长度的分辨率关系?(Unity 5 Heighmap Resolution relationship to terrain width / terrain length?)
  • 如何通知PipedOutputStream线程写入最后一个字节的PipedInputStream线程?(How to notify PipedInputStream thread that PipedOutputStream thread has written last byte?)
  • python的访问器方法有哪些
  • DeviceNetworkInformation:哪个是哪个?(DeviceNetworkInformation: Which is which?)
  • 在Ruby中对组合进行排序(Sorting a combination in Ruby)
  • 网站开发的流程?
  • 使用Zend Framework 2中的JOIN sql检索数据(Retrieve data using JOIN sql in Zend Framework 2)
  • 条带格式类型格式模式编号无法正常工作(Stripes format type format pattern number not working properly)
  • 透明度错误IE11(Transparency bug IE11)
  • linux的基本操作命令。。。