【问题标题】:Finding depth of tree haskell查找树haskell的深度
【发布时间】:2015-01-22 15:52:32
【问题描述】:

我想找到STree 的深度,但在我的代码中它不会计算第一级。

data STree = SNode Label [STree] deriving (Eq,Show)

tdepth :: STree -> Label
tdepth (SNode _ [])= 0
tdepth (SNode l s) = 1 + naiveSumList([tdepth t | t <- s])

naiveSumList :: [Int] -> Label
naiveSumList (x:xs) = x + (naiveSumList xs)
naiveSumList [] = 0

tdepth SNode _ [] 必须给出 1 但我如何计算级别?这是我一直在测试的STrees:

s1 = SNode 1 []
s2 = SNode 1 [
        SNode 2 [],
        SNode 3 []
        ]
s3 = SNode 1 [
        SNode 2 [
            SNode 4 [],
            SNode 5 [],
            SNode 6 []
            ],
        SNode 3 []
        ]
s4 = SNode 1 [
        SNode 2 [
            SNode 4 [],
            SNode 5 [
                SNode 7 []
                ],
            SNode 6 []
            ],
        SNode 3 []
        ]

我的代码示例结果:

tdepth s1  = 0
tdepth s2  = 1
tdepth s3  = 2
tdepth s4  = 3

结果应该是:

 tdepth s1  = 1
 tdepth s2  = 2
 tdepth s3  = 3
 tdepth s4  = 4

【问题讨论】:

  • 请改写您的问题。目前尚不清楚,您指的是哪个代码,您在问题中有两种不同的tdepth 实现。
  • 好的,我删除了另一个
  • 如果你想找到你的树的深度,你为什么要总结每个子分支的深度?您不应该选择该列表中的maximum 吗?另外,当sum 已经存在于Prelude 中时,为什么还要使用naiveSumList
  • @bheklilr 因为我是 Haskell 的新手,我也不知道序曲。树真的很复杂

标签: haskell tree depth


【解决方案1】:

让我们从基本情况开始。你想让tdepth (SNode label [])返回1,所以我们写这个case:

tdepth :: STree -> Int
tdepth (SNode _ []) = 1

现在我们需要知道如何计算树的深度。树的深度是最长分支上的节点数,您对函数的期望示例正是我们正在寻找的。由于我们正在寻找最长的分支,我们应该找到每个分支的最大深度。幸运的是,Prelude 已经内置了 maximum :: Ord a =&gt; [a] -&gt; a 函数,所以我们可以这样做

tdepth (SNode _ branches) = 1 + maximum [tdepth branch | branch <- branches]

或者等价(和我更喜欢的版本)

tdepth (SNode _ branches) = 1 + maximum (map tdepth branches)

但是,我不喜欢 map tdepth branches 周围的括号,因为我们正在使用 Int,我们可以使用 succ 函数,它只需将 1 加到 Int 传递给它的任何内容:

tdepth (SNode _ branches) = succ $ maximum $ map tdepth branches

但是你可以使用任何你喜欢的版本,这三个几乎是等价的。

我们现在一起拥有

tdepth :: STree -> Int
tdepth (SNode _ []) = 1
tdepth (SNode _ branches) = 1 + maximum (map tdepth branches)

我确实还有一个问题,我们已经重复了单个节点深度的逻辑,有什么办法可以将这个问题减少到我们Don't Repeat Ourselves 的地方吗?如果不是检查基本情况,而是想办法让maximum 返回0 如果branches == [],那么我们的函数就不需要两个语句。不幸的是,如果传递一个空列表,maximum 当前会出错,但我们可以非常简单地解决这个问题。我们所要做的就是确保传递给maximum 的列表中始终至少包含一个元素:

tdepth :: STree -> Int
tdepth (SNode _ branches) = 1 + maximum (0 : map tdepth branches)
-- Or if you prefer
--                        = succ $ maximum $ 0 : map tdepth branches

我们可以安全地将0 添加到我们的深度,因为我们知道我们的深度将始终大于 0,因此在该列表上调用 maximum 将返回有效结果。现在我们有了一个表达式,可以准确地计算树的深度,而无需处理任何特殊情况。

【讨论】:

  • 感谢您的解释。
猜你喜欢
  • 1970-01-01
  • 2012-10-12
  • 2014-02-09
  • 2017-07-16
  • 1970-01-01
  • 2020-04-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多