Haskell 创建大小为n的所有布尔二叉树
我试图创建所有大小为n的二叉树,但想不出一种方法 树的定义如下Haskell 创建大小为n的所有布尔二叉树,haskell,functional-programming,binary-tree,Haskell,Functional Programming,Binary Tree,我试图创建所有大小为n的二叉树,但想不出一种方法 树的定义如下 > data Tree :: * -> * where > Tip :: a -> Tree a > Bin :: Tree a -> Tree a -> Tree a > deriving (Eq,Show) 一棵树的大小是它拥有的小费和垃圾箱的数量 我需要创建一个函数,该函数获取一个intn,并返回该大小的所有树的列表 > getTrees ::
> data Tree :: * -> * where
> Tip :: a -> Tree a
> Bin :: Tree a -> Tree a -> Tree a
> deriving (Eq,Show)
一棵树的大小是它拥有的小费和垃圾箱的数量
我需要创建一个函数,该函数获取一个intn
,并返回该大小的所有树的列表
> getTrees :: Int -> [Tree Bool]
例如,对于getTrees 1
我应该得到[Tip True,Tip False]
,因为这是大小为1的所有可能的树
我想不出一种方法来生成所有大小为n的树。好吧,我想有些人不喜欢我试图得出解决方案的方法,因此没有进一步的原因:这里有一个:
getTrees::Int->[Tree Bool]
getTrees 1=[提示为真,提示为假]
getTrees n=do
leftSize好吧,我想有些人不喜欢我试图引出解决方案的方式,因此没有进一步的原因:这里有一个:
getTrees::Int->[Tree Bool]
getTrees 1=[提示为真,提示为假]
getTrees n=do
leftSize让我们先从简单的树开始:大小为1的树:
> getTrees :: Int -> [Tree Bool]
> genTrees 1 = [Tip True, Tip False]
现在,我们必须考虑更大的Int
s。那么2
呢?结果表明,如果Bin
和Tip
都增加大小,则不存在任何大小为2的树。任何Bin
都会导致额外的1+k+j
,其中k
和j
必须是有效的树大小。可以看出,这只会产生奇数大小的树
因此,我们可以在继续之前丢弃任何无效的Int
s:
> genTrees n | even n || n <= 0 = []
> genTrees n =
练习
- 证明列表中使用的所有大小都有效,包括生成的树大小以及中间树大小
- 虽然第二段提供了一些动机,但它没有提供一个完整的证据,证明有效的树必须有奇数大小。证明那句话
- 现在只将
Tip
计算为大小。现在有效的树大小是多少
- 重写上面的算法,以便生成树,其中只有
Tip
s对大小有贡献(毕竟,只有它们有有效负载)
让我们先从简单的树开始:大小为1的树:
> getTrees :: Int -> [Tree Bool]
> genTrees 1 = [Tip True, Tip False]
现在,我们必须考虑更大的Int
s。那么2
呢?结果表明,如果Bin
和Tip
都增加大小,则不存在任何大小为2的树。任何Bin
都会导致额外的1+k+j
,其中k
和j
必须是有效的树大小。可以看出,这只会产生奇数大小的树
因此,我们可以在继续之前丢弃任何无效的Int
s:
> genTrees n | even n || n <= 0 = []
> genTrees n =
练习
- 证明列表中使用的所有大小都有效,包括生成的树大小以及中间树大小
- 虽然第二段提供了一些动机,但它没有提供一个完整的证据,证明有效的树必须有奇数大小。证明那句话
- 现在只将
Tip
计算为大小。现在有效的树大小是多少
- 重写上面的算法,以便生成树,其中只有
Tip
s对大小有贡献(毕竟,只有它们有有效负载)
好的,你试过什么?您对列表的理解或do
语法了解多少。。。提示:让位n=如果n==0,则[[]]否则[True:bs | bs如果n>1
那么树必须是一个Bin
。如果是这样,那么它的子树必须有大小n-1
。因为正好有两个子树,这只是找到所有的数字j,k>1
,这样j+k=n-1
@Zeta-doh…事实上我一直到4;)这也是我的感觉(事实上,我只是在我的示例解决方案中检查了一些案例)…但是你知道:Zeta通常是对的^^^好的,你尝试了什么?你对理解或列表的do
语法了解多少?…提示玩这个:让位n=如果n==0,那么[[]]否则[True:bs | bs如果n>1
那么树必须是一个Bin
。如果是这样,那么它的子树必须有大小n-1
。因为正好有两个子树,这只是找到所有的数字j,k>1
,这样j+k=n-1
@Zeta-doh…事实上我一直到4;)这也是我的感觉(事实上,我只是在样品溶液上检查了几个案例)…但你知道:泽塔通常是对的,他非常迂腐,你只需要-XGADTSyntax
。树的类型不是实际的GADT。而且,最初的问题是本质上不同的-在OP中甚至没有任何大小相同的树。我对第二点进行了评论-第一点应该是非常irr要说我很迂腐,你只需要-XGADTSyntax
。树
类型不是一个实际的GADT。而且,最初的问题本质上是不同的-在OP中甚至没有任何大小相同的树具有规格。我对第二点进行了评论-第一点应该是非常不相关的IMO@EliBraginskiy:如果你当然,您可以将a
限制为Enum a
。Enum a=>Int->[Tree a]
所需的是另一种基本情况。但是,您可能希望使用(有界a,Enum a)=>Int->[Tree a]
。返回Enum a
(其中Enum是(Int->[a]中的函数)这正是我所想的,你能告诉我这样实现它的方向吗?不需要把n
作为参数吗?Bounded
+Enum
使这更容易:getTrees 1=map Tip[minBound..maxBound]
Enum
给你成功
和pred
(和fromnum
和toEnum
和[x..y]
),Bounded
为您提供maxBound
和minBound
,在有限的succ
之后,succ(succ…(succ-minBound)。。