【问题标题】:Subsets of elements of a list in HaskellHaskell中列表元素的子集
【发布时间】:2015-05-17 19:52:30
【问题描述】:

谁能帮我生成给定集合的所有子集?

示例:如果我有 [2,3,4] 并且我想要 K=2,这意味着我需要两个成对的 => [[2,3], [3,2], [2,4] , [4,2], [3,4], [4,3]]

我写了这段代码,但它只生成子集的数量:

arrange::Int->Int->Int
arrange n 1=n
arrange n r=n*arrange (n-1) (r-1)

另一个版本,但这不会生成子集的所有解决方案:

  arrange 0 _ =[[]]
  arrange _ []=[]
  arrange n (x:xs)=(map(x:)) (arrange (n-1) xs)++
                   (arrange n xs)

【问题讨论】:

  • 没有。但是,如果您对我的示例有任何想法,请帮助我实现。
  • 适当的名称是子集,而不是“列表的排列”。请更新您的问题。我已经为您正在寻找的内容添加了答案..
  • @DeJaVo,不,这也不是合适的名称。 “子集”表明顺序无关紧要。根据维基百科,这些被称为“部分排列”,或者当特定大小已知时,“n 的 k 排列”(例如,3 的 2 排列)。

标签: haskell


【解决方案1】:

根据您的示例,这是一个可能的解决方案:

import Data.List (permutations)

pick :: Int -> [a] -> [[a]]
pick 0 _ = [[]]
pick _ [] = []
pick n (x:xs) = map (x:) (pick (n-1) xs) ++ pick n xs

arrange :: Int -> [a] -> [[a]]
arrange n = concatMap permutations . pick n

示例

λ> arrange 2 [2,3,4]
[[2,3],[3,2],[2,4],[4,2],[3,4],[4,3]]

如您所见,诀窍只是挑选一些元素,然后获取结果的所有排列(使用concatMap 将它们连接在一起)

当然,这可能是家庭作业,所以您可能想自己实现permutations ;)

【讨论】:

  • 我为排列写了代码,但还是不行。 'import Data.List (delete)' pick :: Int -> [a] -> [[a]] pick 0 _ = [[]] pick _ [] = [] pick n (x:xs) = map ( x:) (pick (n-1) xs) ++ 选择 n xs 排列 :: [a] -> [[a]] 排列 [] = [[]] 排列 xs = [ x:ys | x [a] -> [[a]] 排列 n = concatMap permutations 。选择n
  • 我收到此错误:错误文件:{Hugs}\An III\Haskell\aranj2.hs:10 - 无法证明显式类型绑定中的约束 *** 表达式:排列 *** 类型:[ a] -> [[a]] *** 给定上下文:() *** 约束:Eq a
  • 如果我用这个排列修改排列声明 :: Eq a => [a] -> [[a]],我会收到此错误:无法证明显式类型绑定中的约束 * ** 表达式:排列 *** 类型:Int -> [a] -> [[a]] *** 给定上下文:() *** 约束:Eq a
  • 很好地使用delete,您必须在使用它的任何地方都包含Eq a(包括我的arrange),但是有一种方法(很明显)可以在不删除的情况下编写permutations;) - 但你的很好 - 只需添加约束
  • 感谢您的指点。这对我帮助很大。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-03-02
  • 2023-03-31
  • 2013-04-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多