微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Haskell数据声明:在二叉树中查找叶子的总和

如何解决Haskell数据声明:在二叉树中查找叶子的总和

这是一棵二叉树,我正在尝试计算叶子的总和

             -1
            /   \
          -5     10
          / \   
        -4  30  
        / \
       13  17

给出了数据声明。

data Tree = TNode Int [ Tree ] | TLeaf Int 

这是我的代码

let t = TNode (-1) [TNode (-5)  [  TNode (-4) [ Tleaf 13,Tleaf 17],Tleaf 30 ],Tleaf 10 ]

sumLeaves (Tleaf x)= x
sumLeaves (TNode x [tree])=  sum[sumLeaves tree]

当我运行程序sumLeaves t时,表明函数sumLeaves中存在非穷尽模式。我认为问题是当有两个叶子的节点时,程序无法计数,但是我不这样做不知道如何解决。非常感谢您的帮助。

编辑: 测试1:

 sumLeaves1 (Tleaf x)= [x]
    sumLeaves1 (TNode x [Tleaf y])=[y]
    sumLeaves1 (TNode x (y:ys))= sum ( (sumLeaves1 y) ++ (sumLeaves1 (TNode x ys)) )

测试2:

 sumLeaves (Tleaf x)= x
    sumLeaves (TNode x [Tleaf y])=y
    sumLeaves (TNode x (y:ys))= (sumLeaves y) + sumLeaves (TNode x ys)

测试2正常工作,但是测试1给出了错误,当我删除sum()时,它给出了一个列表[13,17,30,10],这是正确的列表,但是> sum([13,10])在程序中工作。我该如何克服?

解决方法

您的(Tnode x [tree])仅在节点具有个完全一棵子树时匹配。您应该匹配sublistlist的任何值,所以:

sumLeaves :: Tree -> Int
sumLeaves (Tleaf x) = x
sumLeaves (TNode x trees) = sum (…)

此处应该创建该节点的子代之和的列表。因此,您应该为trees中的每个元素进行映射。我将其保留为练习。您可能想看看map :: (a -> b) -> [a] -> [b]

话虽如此,您不必自己对元素进行求和。您可以提升Tree数据类型并利用DeriveFoldable extension让Haskell为您派生一个Foldable实例:

{-# LANGUAGE DeriveFoldable #-}

data Tree a = TNode a [ Tree a ] | TLeaf a deriving Foldable

sum :: (Foldable f,Num a) => f a -> a是在任何Foldable上定义的,因此我们可以求和:

Prelude> sum (TNode (-1) [TNode (-5)  [  TNode (-4) [ TLeaf 13,TLeaf 17],TLeaf 30 ],TLeaf 10 ])
60

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。