嘿伙计们我有问题。我想删除一棵树的所有叶子。
我的树的初始值是data NBaum a = NBlatt a | NKnoten a [NBaum a]
。我不知道我怎么能这样做,这是Nblatt空的命令。也许你们可以帮助我。
我的函数应该将NBaum作为输入,输出也是NBaum。entferneBlaetter :: NBaum a -> NBaum a
我已经尝试过这段代码,但这是错误的:
entferneBlaetter (NBlatt _) = NBlatt "test"
entferneBlaetter (NKnoten a b) = NKnoten a (entferneBlaetter_help b)
答案 0 :(得分:0)
这是一个提示。
在处理NKnoten a b
时,我们希望:
b
列表中的所有树:
基本方法可能是递归编写entferneBlaetter_help
。
顺便说一句,我认为最好使用entferneBlaetter :: NBaum a -> Maybe (NBaum a)
实现此练习。
答案 1 :(得分:0)
一些暗示,如果你已经走到这一步,道歉:
因为在Haskell中,你的树是不可变的,所以从中删除一些东西意味着在没有它的情况下构造一棵新树。因此类型为entferneBlaetter :: NBaum a -> NBaum a
。
如果允许,您的所有叶子似乎都是NBlatt a
个节点,或者可能是NKnoten a []
个节点。但请注意,一旦你下降到NKnoten
节点,就太晚了;如果没有一棵树,你就无法回归建造一座树。
但是您始终首先扫描父分支,并且叶节点的父节点始终为NKnoten
。因此,您可以尝试filter
子节点列表。但是,这可能会为您留下一个裸分支NKnoten a []
。因此,如果您允许更改entferneBlaetter的类型签名,则可以将Maybe NBaum
传递给调用者,然后可以检查所有子节点是否已评估为Nothing
,然后传回修剪后的分支或将NKnoten a []
替换为NBlatt a
。
作为奖励,如果您的树由单个叶节点组成,则您可以将其修剪为Nothing
。但是,如果您的界面已修复,您仍然可以定义辅助函数entferneBlaetter' :: NBaum -> Maybe NBaum
。
或者,您可以制作第二个转换过程,用NKnoten a []
替换NBlatt a
的所有实例。
答案 2 :(得分:0)
问题不是100%根据叶子的构成指定的,以及当树只有一个节点时会发生什么。但是,如果我们想出“叶子”的定义......
isLeaf :: NBaum a -> Bool
isLeaf (NBlatt _) = True
isLeaf (NKnoten _ []) = True
isLeaf _ = False
...我们可以给出一个递归解决方案,对列表中不是叶子的每个节点进行递归,或者删除它,如果它是。
entferneBlaetter :: NBaum a -> NBaum a
entferneBlaetter (NKnoten s xs) = NKnoten s [entferneBlaetter x | x <- xs, not $ isLeaf x]
entferneBlaetter x = x