【问题标题】:Delete all leaves in a tree in Haskell在 Haskell 中删除树中的所有叶子
【发布时间】:2017-05-23 15:39:02
【问题描述】:

大家好,我有问题。我想删除一棵树的所有叶子。 我的树的初始值是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)

【问题讨论】:

  • entferneBlaetter (NBlatt 1) 应该评估什么?
  • 如果你给方法一个NBlatt作为初始值呢?你不能从一片叶子中移除一片叶子......
  • 此外,代码本身一开始并没有错,它只取决于您将如何处理entferneBlaetter_help
  • 你的树可以保存多少个a 值?它可以保存一个a 值吗? (有多少种方式?)叶子是树吗? (它是,根据数据定义)。如果从 1 元素叶树中删除叶,结果不应该保持零 a 值吗?你的树可以保持零a 值吗? Nblatt 7NKnoten 7 [] 有区别吗?你真的需要Nblatt a吗?
  • 最好明确定义“叶子”的含义,因为NBlatt "test"NKoten "test" [] 都不会“递归”并保留其他节点。两个都要删除吗?

标签: haskell tree


【解决方案1】:

这里有一个提示。

在处理NKnoten a b时,我们希望:

  • 扫描b列表中的所有树:
    • 如果我们找到一棵叶子树,我们会将其从列表中删除
    • 如果我们找到一个节点树,我们会递归地从该节点的子树中删除叶子,并将结果保留在列表中。

一个基本的方法是递归地写你的entferneBlaetter_help

顺便说一句,我认为这个练习最好使用entferneBlaetter :: NBaum a -> Maybe (NBaum a) 来实现。

【讨论】:

    【解决方案2】:

    一些提示,如果您已经走到这一步,请道歉:

    因为在 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

    【讨论】:

      【解决方案3】:

      问题不是 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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-09-27
        • 2019-12-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多