F#的新手 我正在尝试翻转树枝上的子树。
我们必须使用以下数据类型
df = df.set_index('Name1')
df.loc[:, 'Money_1'] = df2.set_index('Name').Money
df = df.reset_index().set_index('Name2')
df.loc[:, 'Money_2'] = df2.set_index('Name').Money
df.reset_index()
示例树
Name1 Name2 Money_1 Money_2
0 John Jack 40.0 10.0
1 Eva Tom 20.0 80.0
2 Eva Sara 20.0 34.0
3 Carl Sam 77.0 NaN
4 Sam Erin NaN 12.0
到目前为止,这是我的代码:
type btree = Empty | Node of btree * int * btree
type finding = NotFound | Found of int
示例输入和输出:
let s = Node (Node(Empty, 5, Node(Empty, 2, Empty)), 3, Node (Empty, 6, Empty))
(*
(3)
/ \
(5) (6)
/ \ | \
() (2) () ()
/ \
() ()
*)
会返回
let rec mirror t = function
| Node(Empty, t, Empty) -> t
| Node (t1, t, t2) ->
| _ -> failwith "Empty"
现在,代码无法完成任何工作,我需要有关如何移动节点以获取所需镜像树的帮助。
我想知道是否必须实现另一个用于删除/插入节点的功能?任何帮助将不胜感激!
答案 0 :(得分:1)
镜像意味着将左分支变为右分支,将右分支变为左分支。因此,在您的递归函数中执行此操作。例如,如果您从一个基本的3节点树开始:
1
2 3
然后将镜像
1
3 2
因此在代码中表示:
let rec mirror t = function
| Node(Empty, t, Empty) -> t
| Node (left, value, right) -> Node (right, value, left)
除非这不适用于较大的树木,但这是一个开始。您真正想要的是左右节点的镜像。您应该能够通过在match子句的最后一行的正确位置添加2个对mirror的调用来完成上述功能。
答案 1 :(得分:1)
这似乎是家庭作业,因此在“移交”解决方案之前,我将添加一些学习要点。让我们看看您已经编写的代码,这不是一个糟糕的开始。我将其粘贴在下面以供参考。
let rec mirror t = function
| Node(Empty, t, Empty) -> t
| Node (t1, t, t2) ->
| _ -> failwith "Empty"
通过添加rec
关键字,开始允许函数递归调用自身。您这样做是对的,实际上这是一个非常重要的认识,执行此任务的方法是创建一个递归函数。因为,实际上,“镜像”一棵树意味着什么?镜像意味着在每个节点上翻转子树的顺序,并镜像每个子树。
这是一个递归定义,因为要镜像节点,则需要镜像子树。因此,添加rec
关键字是正确的。但是,在您的代码中,您没有正确处理终端状态Empty
。使用btree
定义,您将最终看到一棵Empty
树,这意味着您将最终抛出异常(使用{{1} }。这显然不是期望的行为。一棵空树的镜子是什么样的?空!然后,处理这种情况的方法是将failwith
替换为| _ -> failwith "Empty"
。
现在,在F#中,| Empty -> Empty
只是let foo = function | ...
的语法糖,这意味着您的函数实际上使用了两个参数:let foo <arg> = match <arg> with | ...
和一个隐藏的参数由t
糖制成。我想这不是您想要的,所以您应该删除当前未使用的参数function
,或将t
替换为function
。
参数match t with
当前未使用的原因是,t
在匹配情况t
中反弹到整数节点值。这也意味着编译器当前的最佳猜测是,| Node(..., t, ...)
的返回类型应该是mirror
,而不是int
,因为在第一个返回的是btree
情况。
最后一点是,没有理由直接使用空子树处理案件,因为它们也只是int
。
牢记上述所有内容,我希望我的解决方案是合理的
btree