你如何计算 Haskell 列表中的所有列表组合?
Posted
技术标签:
【中文标题】你如何计算 Haskell 列表中的所有列表组合?【英文标题】:How do you compute all combinations of lists within a list in Haskell? 【发布时间】:2022-01-16 08:50:25 【问题描述】:正如问题所述,我有一个多维列表,我想计算一个列表,其中包含这些列表的所有可能组合。 我只有一个用于一维列表的函数,如下所示:
combinations :: [a] -> [[a]]
combinations xs = [ [x,y] | x <- xs, y <- xs]
【问题讨论】:
您的解决方案允许重复:您可以为列表[1,2,3]
生成[2,2]
。这是预期的行为,还是“错误”?如果没有重复,看起来你想生成所有可能的排列。
是的,需要这种行为。这同样适用于列表中的列表组合。
但是combinations [1,2,3]
的输出是什么? [1,1,1]
、[1,1,2]
等等?我们什么时候停止“挑选”元素?例如,我不太清楚combinations [1,2,3]
的预期输出应该是什么。
组合 [1,2,3] 的输出为:[[1,1],[1,2],[1,3],[2,1],[2,2 ],[2,3],[3,1],[3,2],[3,3]]。但是我不能对多维列表使用相同的解决方案。多维列表所需的输出如下所示:combinationsM [[1,2],[3,4]] = [[[1,2],[3,4]],[[3,4], [1,2]]]
如果你使用列表,比如[[1], [2,3]]
,它将作为组合返回[[[1],[1]], [[1], [2,3]], [[2,3], [1]], [[2,3], [2,3]]]
【参考方案1】:
多维列表所需的输出如下所示:
combinationsM [[1,2],[3,4]] = [[[1,2],[3,4]],[[3,4],[1,2]]]
您的combinations
函数处理元素列表的列表。它只是看到一个列表,而这些列表中的项目就是列表,但是函数并不关心这个。对于[[1,2], [3,4]]
,它将因此返回:
ghci> combinations [[1,2], [3,4]]
[[[1,2],[1,2]],[[1,2],[3,4]],[[3,4],[1,2]],[[3,4],[3,4]]]
因此,它有两次[1,2]
、[1,2]
和[3,4]
、[3,4]
和[1,2]
以及两次[3,4]
的组合。
因此,您的函数已经返回子列表的组合。它只适用于任何类型的列表。
如果您想删除两次选择相同子列表的组合,您可以定义一个助手来选择一个元素并返回剩余元素的列表:
pick :: [a] -> [(a, [a])]
pick [] = []
pick (x:xs) = (x, xs) : map … …
…
部分留作练习。该函数应该进行递归调用,并在所有列表前面加上x
在map … …
部分。
这意味着pick [1,4,2,5]
返回[(1, [4,2,5]), (2, [1,4,5]), (4, [1,2,5]), (5, [1,4,2])]
。
然后我们可以在不选择相同元素两次的情况下获得组合:
combinations :: [a] -> [[a]]
combinations xs = [[x, y] | (x, ys) <- pick xs, y <- ys]
返回一个 2 元组的列表可能会更好,这会为返回类型添加更多上下文,因为我们知道组合包含的项数不可能与 2 不同:
combinations :: [a] -> [[a]]
combinations xs = [(x, y) | (x, ys) <- pick xs, y <- ys]
【讨论】:
以上是关于你如何计算 Haskell 列表中的所有列表组合?的主要内容,如果未能解决你的问题,请参考以下文章