【问题标题】:haskell combinations with repetition带有重复的haskell组合
【发布时间】:2020-11-04 02:33:48
【问题描述】:

这是我的函数,它为给定集合中的 k 个项目生成所有组合:

combR :: [t] -> Int -> [[t]]
combR _ 0 = [ [] ]
combR [] k = []
combR (x:xs) k = combR xs k ++ [x:t | t <- combR xs (k-1) ]

但是,它的作用是,它只生成不重复的组合,不包括那些应该重复的组合,例如输入

combR [0,1,2] 2

输出应该是[0,1],[0,2],[1,0],[1,2],[2,0],[2,1]

但只是[0,1],[0,2],[1,2]

【问题讨论】:

  • 您的[x:t | t &lt;- combR xs (k-1) ] 将仅生成以x 开头的组合,因为x :x 添加到列表t 之前。
  • 当你说“有重复”时,我预计预期的输出也应该包括 [0,0], [1,1], ... 但显然你只想要非重复列表的所有排列。也许“重复”在这里不是正确的术语。

标签: haskell


【解决方案1】:

您可以创建一个函数,为列表创建 2 元组列表,其中 x 是从列表中“弹出”的元素:

import Control.Arrow(second)

pickOne :: [a] -> [(a, [a])]
pickOne [] = []
pickOne (x:xs) = (x, xs) : map (second (x:)) (pickOne xs)

这给了我们:

Prelude> pickOne [1,4,2,5]
[(1,[4,2,5]),(4,[1,2,5]),(2,[1,4,5]),(5,[1,4,2])]

在每个 2 元组中,第一个元素是我们从给定列表中选择的元素,第二个元素是剩余元素的列表。

我们可以在列表推导表达式中使用它,从而选择其中一个元素,并在剩余选项列表上递归:

combR :: [t] -> Int -> [[t]]
combR _ 0 = [[]]
combR l k = [ x:xs | (x, rs) <- pickOne l, xs <- combR rs (k-1)]

然后我们可以生成具有给定数量元素的组合:

Prelude Control.Arrow> combR [0,1,2] 2
[[0,1],[0,2],[1,0],[1,2],[2,0],[2,1]]
Prelude Control.Arrow> combR [1,4,2,5] 2
[[1,4],[1,2],[1,5],[4,1],[4,2],[4,5],[2,1],[2,4],[2,5],[5,1],[5,4],[5,2]]
Prelude Control.Arrow> combR [1,4,2,5] 3
[[1,4,2],[1,4,5],[1,2,4],[1,2,5],[1,5,4],[1,5,2],[4,1,2],[4,1,5],[4,2,1],[4,2,5],[4,5,1],[4,5,2],[2,1,4],[2,1,5],[2,4,1],[2,4,5],[2,5,1],[2,5,4],[5,1,4],[5,1,2],[5,4,1],[5,4,2],[5,2,1],[5,2,4]]
Prelude Control.Arrow> combR [1,4,2,5] 4
[[1,4,2,5],[1,4,5,2],[1,2,4,5],[1,2,5,4],[1,5,4,2],[1,5,2,4],[4,1,2,5],[4,1,5,2],[4,2,1,5],[4,2,5,1],[4,5,1,2],[4,5,2,1],[2,1,4,5],[2,1,5,4],[2,4,1,5],[2,4,5,1],[2,5,1,4],[2,5,4,1],[5,1,4,2],[5,1,2,4],[5,4,1,2],[5,4,2,1],[5,2,1,4],[5,2,4,1]]
Prelude Control.Arrow> combR [1,4,2,5] 1
[[1],[4],[2],[5]]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-04-22
    • 1970-01-01
    • 2015-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-18
    相关资源
    最近更新 更多