【问题标题】:Haskell - implement powerset function of a setHaskell - 实现集合的powerset函数
【发布时间】:2020-05-01 16:52:33
【问题描述】:

我刚刚开始学习 Haskell,遇到了解决这个问题的困难时期: powerSet :: Set a -> Set (Set a)

这是我的尝试:

powerSet :: Tree a -> Tree (Tree a)
powerSet Empty = Empty
powerSet tree = fromList' [fromList' p | p <- powerSet' (toList tree)]

powerSet' :: [a] -> [[a]]
powerSet' [] = [[]]
powerSet' (x:xs) = [x:ps | ps <- powerSet' xs] ++ powerSet' xs

我应该按这样的顺序输出:powerset {1,2,3} =&gt; { {}, {1}, {2}, {1,2,3}, {1,3}, {2}, {2,3}, {3} }

但是我得到了这个:powerset {1,2,3} =&gt; { {1,2,3}, {1,2}, {1,3}, {1}, {2,3}, {2}, {3}, {} }

有什么办法可以改变吗?

【问题讨论】:

  • 为什么您希望订单是{ {}, {1}, ... }
  • 集合是无序的集合。很可能,您应该在打印元素时忽略它们的顺序。
  • 您的实现还处理Tree,而不是Set
  • @WillemVanOnsem 值得一提的是,如果您将预期输出中的第一个 {2} 更改为 {1,2},则子集按字典顺序显示;所以也许这个练习是为了鼓励搜索树的实现。
  • @DanielWagner:是的。但是,fromList 应该因此以有序的方式插入项目。那么“责任”更多的是用于树生成部分而不是powerSet'函数。

标签: haskell powerset


【解决方案1】:

想知道有什么办法可以改变吗?

好吧,订单是{ {1,2,3}, {1,2}, {1,3}, {1}, {1,3}, {2,3}, {2}, {3}, {} },因为这就是你实现它的方式。实际上,对于一个空列表,您会返回 powerSet' [],这是一个带有空列表的单例列表。对于非空列表,您在列表的尾部进行递归,首先生成该列表,每次在该列表前面加上 x,然后生成不带前缀的递归调用的结果。

因此对于列表[2],递归的情况是[[]],所以我们首先在它前面加上2,产生[2],然后我们不把它放在前面,产生[]

如果我们这样计算[1,2] 的幂集,递归调用将得到[[2], []]。我们首先发出列表,每次都添加1,因此[1,2][1],然后我们发出不添加前缀的列表,使其成为[2][]。或者把这些放在一起[[1,2], [1], [2], []]

您可以按不同的顺序生成结果,例如:

powerSet' :: [a] -> [[a]]
powerSet' l = [] : go l
    where go [] = []
          go (x:xs) = [x] : map (x:) (go xs) ++ go xs

但是作为@DanielWagner says in his comment:

所以也许这个练习是为了鼓励搜索树的实现。

您可能不应该更改由powerSet' 产生的项目的顺序,但要确保您的Tree 是一个(二进制)搜索树,从而实现@987654341 @ 函数以这样的方式在您的Tree 中以有序的方式插入项目。

【讨论】:

  • 是的,我确实使用了 BST,这非常清楚地解释了我的问题。非常感谢!
猜你喜欢
  • 2020-04-26
  • 1970-01-01
  • 1970-01-01
  • 2018-07-12
  • 1970-01-01
  • 1970-01-01
  • 2021-12-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多