简体   繁体   English

删除Haskell中一棵树上的所有叶子

[英]Delete all leaves in a tree in Haskell

Hey guys i have a problem. 嗨,我有问题。 I would like to delete all leaves of a tree. 我想删除一棵树上的所有叶子。 My init of a tree is data NBaum a = NBlatt a | NKnoten a [NBaum a] 我对树的初始化是data NBaum a = NBlatt a | NKnoten a [NBaum a] data NBaum a = NBlatt a | NKnoten a [NBaum a] . data NBaum a = NBlatt a | NKnoten a [NBaum a] I have no idea how i can do this and which is the command that the Nblatt is empty. 我不知道我该怎么做,这是Nblatt是空的命令。 Maybe u guys can help me. 也许你们可以帮助我。

My function should take a NBaum as an input and the output is a NBaum too. 我的函数应该以NBaum作为输入,输出也应为NBaum。 entferneBlaetter :: NBaum a -> NBaum a

I tried already this code but it's wrong: 我已经尝试过此代码,但这是错误的:

entferneBlaetter (NBlatt _) = NBlatt "test"
entferneBlaetter (NKnoten a b) = NKnoten a (entferneBlaetter_help b)

Here's a hint. 这是一个提示。

When dealing with NKnoten ab , we want to: 在处理NKnoten ab ,我们希望:

  • scan all the trees in the b list: 扫描b列表中的所有树:
    • if we find a leaf tree, we remove it from the list 如果找到叶子树,则将其从列表中删除
    • if we find a node tree, we recursively remove the leaves from the subtrees of that node, and keep the result in the list. 如果找到节点树,则从该节点的子树中递归地删除叶子,并将结果保留在列表中。

A basic approach could be to write your entferneBlaetter_help recursively. 一种基本方法是递归地编写您的entferneBlaetter_help

By the way, I think this exercise would best be realized using entferneBlaetter :: NBaum a -> Maybe (NBaum a) . 顺便说一句,我认为最好使用entferneBlaetter :: NBaum a -> Maybe (NBaum a)实现此练习。

Some hints, apologies if you've gotten this far already: 如果您已经走到这一步,请注意以下几点:

Since, in Haskell, your trees are immutable, removing something from one means constructing a new tree without it. 由于在Haskell中,您的树是不可变的,因此从其中删除某些内容就意味着不用它就可以构造一棵新树。 Hence the type entferneBlaetter :: NBaum a -> NBaum a . 因此,类型entferneBlaetter :: NBaum a -> NBaum a

All your leaves appear to be either NBlatt a nodes, or possibly NKnoten a [] nodes if that's allowed. 您的所有叶子似乎都是NBlatt a节点,或者如果允许的话,可能是NKnoten a []节点。 But observe that, once you descend to a NKnoten node, it's too late; 但是请注意,一旦下降到NKnoten节点,那就来不及了。 there's nothing you can return to construct a tree without one. 没有一棵树,您将无法返回建造一棵树。

But you always scan the parent branch first, and the parent of a leaf node is always a NKnoten . 但是,您总是先扫描父分支,而叶节点的父总是NKnoten So you might try to filter the list of daughter nodes. 因此,您可以尝试filter子节点列表。 This might, however, leave you with a bare branch, NKnoten a [] . 但是,这可能会给您留下光秃秃的分支, NKnoten a [] So, if you're allowed to change the type signature of entferneBlaetter, you could pass a Maybe NBaum up to the caller, and it could then check whether all the daughter nodes evaluated to Nothing , then pass back either the pruned branch or replace NKnoten a [] with NBlatt a . 因此,如果允许您更改entferneBlaetter的类型签名,则可以将Maybe NBaum传递给调用者,然后可以检查是否所有子节点的求值结果都为Nothing ,然后返回修剪的分支或替换NKnoten a [] NBlatt a NKnoten a []

As a bonus, if your tree consists of a single leaf node, you would then be able to prune it to Nothing . 另外,如果您的树由单个叶子节点组成,则可以将其修剪为Nothing But if your interface is fixed, you can still define a helper function entferneBlaetter' :: NBaum -> Maybe NBaum . 但是,如果您的接口是固定的,您仍然可以定义一个辅助函数entferneBlaetter' :: NBaum -> Maybe NBaum

Alternatively, you could make a second transformation pass that replaces all instances of NKnoten a [] with NBlatt a . 或者,您可以进行第二次转换,将NKnoten a []所有实例替换为NBlatt a

The problem isn't 100% specified in terms of what constitutes leaves and what should happen when the tree only has a single node. 没有就叶子的组成以及树只有一个节点时发生的情况100%指定问题。 However, if we come up with a definition of "leaf" ... 但是,如果我们提出“叶子”的定义,则...

isLeaf :: NBaum a -> Bool
isLeaf (NBlatt _)     = True
isLeaf (NKnoten _ []) = True
isLeaf _              = False

... we can give a recursive solution, recursing for each node in the list that is not a leaf, or removing it if it is. ...我们可以提供一个递归解决方案,对列表中不是叶子的每个节点进行递归,如果存在则将其删除。

entferneBlaetter :: NBaum a -> NBaum a
entferneBlaetter (NKnoten s xs) = NKnoten s [entferneBlaetter x | x <- xs, not $ isLeaf x]
entferneBlaetter x              = x

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM